Evan Carroll
Evan Carroll

Reputation: 1

Explicit type signatures for polymorphic types

I'm reviewing Haskell: The Craft of Functional Programming, however the type signatures on page 356 have thrown me for a loop.

Here is a simple one:

succeed :: b -> Parse a b
succeed val inp = [( val, inp )]

How can that be b -> Parse a b, if

succeed Int -> Int
succeed a = a

and,

succeed Int -> Int -> Int
succeed a b = a + b

The amount of arguments your taking has to be in the type declaration right? How can you take val, and imp, if your type declaration only has one type variable: succeed :: b -> Parse a b is supposed to read, take one variable of type a and return a type of Parse a b, not take two variables... where is inp permitted?

Upvotes: 3

Views: 382

Answers (2)

R. Martinho Fernandes
R. Martinho Fernandes

Reputation: 234424

In Haskell all functions take exactly one argument and produce exactly one result. When have a type like this a -> b -> c you have the same as a -> (b -> c). So, instead of a two-argument function, you actually have a function that when given an argument produces another function that takes the second argument and produces the final result.

When you apply a function to two arguments, like this f x y, it's the same as (f x) y. You're actually applying the function that results from f x to the second argument y. From this behavior you get "partial application" for free.

There is a pair of functions in the Prelude named curry and uncurry that let you convert between functions written in this style and functions that take two arguments directly as a pair:

uncurry :: (a -> b -> c) -> ((a,b) -> c)
curry :: ((a,b) -> c) -> (a -> b -> c)

f  :: a -> b -> c
f = ...
f' :: (a,b) -> c
f' = uncurry f

I don't know how Parse was defined, but if you define it as a synonym to a function type (something common with parsers), you get that kind of behavior.

Upvotes: 1

keegan
keegan

Reputation: 1617

Because Parse is a type synonym with -> in its expansion. Example:

type Foo = Int -> Int

succeed :: Int -> Foo
succeed a b = a + b

Upvotes: 8

Related Questions