Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[Haskell-beginners] flip lookup in ghci

1 view
Skip to first unread message

Matt R

unread,
Feb 20, 2009, 5:27:59 AM2/20/09
to begi...@haskell.org
So what's this all about then? How come a has become ()?

ghci> :t lookup
lookup :: (Eq a) => a -> [(a, b)] -> Maybe b
ghci> :t flip lookup
flip lookup :: (Eq a) => [(a, b)] -> a -> Maybe b
ghci> let lookupIn = (flip lookup :: (Eq a) => [(a, b)] -> a -> Maybe b )
ghci> :t lookupIn
lookupIn :: [((), b)] -> () -> Maybe b
_______________________________________________
Beginners mailing list
Begi...@haskell.org
http://www.haskell.org/mailman/listinfo/beginners

Rafael Gustavo da Cunha Pereira Pinto

unread,
Feb 20, 2009, 7:11:24 AM2/20/09
to Matt R, begi...@haskell.org
you are applying the type to lookup only!

try let lookupIn = ((flip lookup ) :: (Eq a) => [(a, b)] -> a -> Maybe b )

--
Rafael Gustavo da Cunha Pereira Pinto
Electronic Engineer, MSc.

Matt R

unread,
Feb 20, 2009, 7:44:39 AM2/20/09
to Rafael Gustavo da Cunha Pereira Pinto, begi...@haskell.org
Rafael Gustavo da Cunha Pereira Pinto <RafaelGC...@gmail.com>:

> you are applying the type to lookup only!
>
> try let lookupIn = ((flip lookup ) :: (Eq a) => [(a, b)] -> a -> Maybe b )

Oops, I didn't mean to include my attempts at type annotation in my
previous email...I meant to write

ghci> let lookupIn = flip lookup

But it doesn't seem to make any difference either way. I still get

ghci> :t lookupIn
lookupIn :: [((), b)] -> () -> Maybe b

regardless :(

-- Matt

Felipe Lessa

unread,
Feb 20, 2009, 8:06:17 AM2/20/09
to Matt R, begi...@haskell.org, Rafael Gustavo da Cunha Pereira Pinto
Let's try to see what is going on using GHCi 6.10.1:

Prelude> :t lookup


lookup :: (Eq a) => a -> [(a, b)] -> Maybe b

Prelude> :t flip lookup
flip lookup :: (Eq a) => [(a, b)] -> a -> Maybe b

Everything ok. Lets try binding:

Prelude> let f = flip lookup
Prelude> :t f
f :: [((), b)] -> () -> Maybe b

Woops. Whenever you see a type of a function becoming less polymorphic
than you expected, try adding a parameter:

Prelude> let g x = flip lookup x
Prelude> :t g
g :: (Eq a) => [(a, b)] -> a -> Maybe b

Nice! Let's try again without the monomorphism restriction[1]

Prelude> :s -XNoMonomorphismRestriction
Prelude> let h = flip lookup
Prelude> :t h
h :: (Eq a) => [(a, b)] -> a -> Maybe b
Prelude> :s -XMonomorphismRestriction

So, that's where the culprit lies! As we declared 'f' without a type
signature and without explicit arguments, the monomorphism restriction
didn't let us overload our function with the 'Eq' class.

Note that if we activated all warnings, GHC would tell us that
something is wrong:

Prelude> :s -Wall
Prelude> let j = flip lookup
<interactive>:1:13:
Warning: Defaulting the following constraint(s) to type `()'
`Eq a' arising from a use of `lookup' at <interactive>:1:13-18
In the first argument of `flip', namely `lookup'
In the expression: flip lookup
In the definition of `j': j = flip lookup

We can't just remove the 'Eq' constraint, if we want to refine the
type of 'lookup' then we need to supply something that implements
'Eq'. As GHC doesn't know what you want to do, it just defaults to ().
If, for example, you used the new function in the same let-binding,
GHC would infer another type and show no warnings:

Prelude> let k = flip lookup; l = k [] (1 :: Int)
Prelude> :t k
k :: [(Int, b)] -> Int -> Maybe b

But note that even if you use the function where you defined it, it
can't be polymorphic

Prelude> let m = flip lookup; n = m [] (1 :: Int); o = m [] (1 :: Double)
<interactive>:1:52:
Couldn't match expected type `Int' against inferred type `Double'
In the second argument of `m', namely `(1 :: Double)'
In the expression: m [] (1 :: Double)
In the definition of `o': o = m [] (1 :: Double)

In short: add an explicit parameter or use a type signature. =)

Hope that helps!

[1] http://www.haskell.org/haskellwiki/Monomorphism_restriction

--
Felipe.

Magnus Therning

unread,
Feb 20, 2009, 8:06:29 AM2/20/09
to Matt R, begi...@haskell.org, Rafael Gustavo da Cunha Pereira Pinto
On Fri, Feb 20, 2009 at 12:44 PM, Matt R <mattrus...@googlemail.com> wrote:
> Rafael Gustavo da Cunha Pereira Pinto <RafaelGC...@gmail.com>:
>> you are applying the type to lookup only!
>>
>> try let lookupIn = ((flip lookup ) :: (Eq a) => [(a, b)] -> a -> Maybe b )
>
> Oops, I didn't mean to include my attempts at type annotation in my
> previous email...I meant to write
>
> ghci> let lookupIn = flip lookup
>
> But it doesn't seem to make any difference either way. I still get
>
> ghci> :t lookupIn
> lookupIn :: [((), b)] -> () -> Maybe b
>
> regardless :(

Indeed, how funky:

GHCi, version 6.8.2: http://www.haskell.org/ghc/ :? for help
Loading package base ... linking ... done.
Prelude> :t flip lookup
flip lookup :: (Eq a) => [(a, b)] -> a -> Maybe b
Prelude> let lookupIn = flip lookup
Prelude> :t lookupIn


lookupIn :: [((), b)] -> () -> Maybe b

Prelude>

/M

--
Magnus Therning (OpenPGP: 0xAB4DFBA4)
magnus@therning.org Jabber: magnus@therning.org
http://therning.org/magnus identi.ca|twitter: magthe

0 new messages