Expedito
Expedito

Reputation: 7795

How to get Haskell to recognize functions as applicative functors

I'm new to Haskell and still don't understand how to deal with their type system. My problem is that I'm playing around with the sequenceA function from the book Learn You a Haskell For Great Good. Here's the function:

sequenceA :: (Applicative f) => [f a] -> f [a]
sequenceA = foldr (liftA2 (:)) (pure [])

I tried to adapt it to a specific use, so I wrote the following function:

binner :: Int -> [Int -> Int]
binner n = (map (\x -> bin x) [n, (n-1) .. 1])
  where bin n = (`mod` 2) . (`div` 2^(n-1))

I have no problem using these functions separately. For example, the following works great in GHCi:

sequenceA (binner 4) 10

If I type the following in GHCi,

:t (sequenceA (binner 4))

It shows the type as:

(sequenceA (binner 4)) :: Int -> [Int]

However, I can't figure out how to combine the functions. Intuitively, it seems I should be able to do the following, using the same type that GHCi showed:

binner :: Int -> [Int]
binner n = foldr (liftA2 (:)) (pure []) $ (map (\x -> bin x) [n, (n-1) .. 1])
  where bin n = (`mod` 2) . (`div` 2^(n-1))

But that throws an error compiling:

Couldn't match type ‘[a0]’ with ‘Int’ Expected type: [Int] Actual type: [[a0]]

I tried messing with the type declaration, but haven't figured out how to fix it.

Thanks for the help!

Upvotes: 2

Views: 104

Answers (1)

You tried to use the type of sequenceA (binner 4) with the body of essentially \n -> sequenceA (binner n). Since what you wrote takes an Int that what you gave to :t doesn't, you need to add an Int -> to the beginning of the type signature to represent the n:

binner :: Int -> Int -> [Int]
binner n = foldr (liftA2 (:)) (pure []) $ (map (\x -> bin x) [n, (n-1) .. 1])
  where bin n = (`mod` 2) . (`div` 2^(n-1))

You could instead keep the type, but hardcode the 4:

binner :: Int -> [Int]
binner = foldr (liftA2 (:)) (pure []) $ (map (\x -> bin x) [4, (4-1) .. 1])
  where bin n = (`mod` 2) . (`div` 2^(n-1))

Upvotes: 3

Related Questions