Jayyyyyy
Jayyyyyy

Reputation: 197

type signature of Haskell

cow :: (Eq a) => a -> a -> [a] -> Bool
cow x y z = x && y `elem` z

 foo ::
 foo x y z = x `elem` y && y `elem` z

 bar::
 bar x y = case y of
    Nothing -> x
    Just z  -> x + z

I don't know what the type signature should be.

Upvotes: 1

Views: 530

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477607

In order to determine the type signatures. You do not need to know what a function is doing. You can use the type signatures of the functions you use, and do inference on that.

Since the type signature of your cow function is not entirely correct, we will show how to derive the type signature of the cow function, and then leave the two others as exercises.

We see that cow here has three parameters: x, y and z. At the moment, we do not know much about x, y and z. So we will assign a different type variable for these variables. So x :: a, y :: b and z :: c.

Next we can start to derive the types. The function definition of cow:

cow x y z = x && y `elem` z

can be written in a more canonical format as:

cow x y z = (&&) x (elem y z)

We thus see that we make use of two functions here: (&&) :: Bool -> Bool -> Bool, and elem :: (Eq e, Foldable f) => e -> f e -> Bool, we here use e instead of f to avoid "name clashes" with our already defined type variable a. Since we use x as argument of the (&&) :: Bool -> Bool -> Bool function, we know that x should have type Bool, and thus that a ~ Bool (a is the same type as Bool). Furthermore we thus know that (&&) x :: Bool -> Bool.

Next we see that we call elem :: (Eq e, Foldable f) => e -> f e -> Bool. This thus means that y, which is the first parameter applied to elem thus has type e, and therefore b ~ e.

It furthermore means that elem x thus has type (Eq e, Foldable f) => f e -> Bool, and we apply this function to the z parameter. This thus means that c ~ (Eq e, Foldable f) => f e, and that the type of elem y z is Bool.

Since the type of elem y z is Bool, this matches with the function (&&) x, and thus the type of (&&) x (elem y z) is thus Bool.

We thus have derived that:

x :: Bool
y :: e
z :: f e

with as type constraints Eq e and Foldable f. This thus means that cow has as function:

cow :: (Eq e, Foldable f) => Bool -> e -> f e -> Bool
cow x y z = x && y `elem` z

Upvotes: 3

Related Questions