[Haskell-beginners] question on typeclasses and applicatives

Daniel Fischer daniel.is.fischer at web.de
Thu Sep 2 15:19:58 EDT 2010


On Thursday 02 September 2010 21:02:33, Alec Benzer wrote:
> I came up with some code when trying to understand applicatives:
>
> import Control.Applicative
> import qualified Data.Map as M
>
> instance Applicative (M.Map String) where
>   pure x = M.fromList [("",x)]
>   fs <*> xs = M.fromList [(k1 ++ " " ++ k2,v1 v2) | k1 <- M.keys fs, k2
> <- M.keys xs, v1 <- M.elems fs, v2 <- M.elems xs]
>
> 1. When I :load this in ghci it gives me some error about using (M.Map
> String) here, and tells me it'll work if I use the -XFlexibleInstances
> flag. Why is this type of behavior disabled by default?

Because the language specification imposed that instance declarations must 
have the form

instance Class (T a1 a2 ... an) where ...

where T is a type constructor, 0 <= n and a1, a2, ..., an are *distinct* 
type variables.

> Is it potentially dangerous in some way?

I know of no dangers off the top of my head.

>
> 2. When running the following:
>
>        fromList [("double",(*2))] <*> fromList[("two",2),("seven",7)]
>
> I get:
>
>         fromList [("double seven",4),("double two",4)]
>
> instead of what I'd expect:
>
>         fromList [("double seven",14),("double two",4)]

That's because you really get

fromList [("double seven", (*2) 7),("double seven", (*2) 2), ("double two", 
(*2) 7), ("double two", (*2) 2)]

and later values for the same key overwrite earlier.

You probably wanted

  fs <*> xs = M.fromList [(k1 ++ " " ++ k2, v1 v2) | (k1,v1) <- M.assocs 
fs, (k2,v2) <- M.assocs xs]

>
> Although this:
>
>         (*2) <$> fromList[("two",2),("seven",7)]
>
> gives what I'd expect:
>
>         fromList [("seven",14),("two",4)]
>
> Why is this happening? I can't seem to figure it out.



More information about the Beginners mailing list