简体   繁体   中英

How do I determine the type of a function?

Suppose I have a function like map zipWith , how can I determine its type? Given that the type of zipWith is (a -> b -> c) -> [a] -> [b] -> [c] and that of map is (a -> b) -> [a] -> [b]

Similarly how do I determine types of functions like zipWith sum ?

You can check the type in GHCi with :t , as mentioned in the other answers. If you want to try figuring it out yourself, you need to substitute the types as appropriate. In your first example, we have

zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]

and

map :: (a -> b) -> [a] -> [b]

The first argument of map is a function of one argument, so we have to regard zipWith as such a function:

zipWith :: (a -> b -> c) -> ([a] -> [b] -> [c])

(The type above is equivalent to the original one. It means zipWith converts a function which takes arguments of types a and b to a function which takes lists of a and b .)

map can be seen as a function of one argument as well:

map :: (a -> b) -> ([a] -> [b])

Now, we fill in the types in map 's result type - a becomes a -> b -> c and b becomes [a] -> [b] -> [c] :

map zipWith :: [a -> b -> c] -> [[a] -> [b] -> [c]]

PS: Do you really want functions which take lists of functions as arguments? If you just want to zip two lists adding the corresponding elements you want

 zipWith (+) :: Num c => [c] -> [c] -> [c]

rather than zipWith sum .

You can see its type in ghci:

ghci> :t map zipWith
map zipWith :: [a -> b -> c] -> [[a] -> [b] -> [c]]

Similarly for zipWith sum :

ghci> :t zipWith sum
zipWith sum :: Num (b -> c) => [[b -> c]] -> [b] -> [c]

That's what ghci is there for! Or you can just use tryhaskell.org

> :t map zipWith
:: [a -> b -> c] -> [[a] -> [b] -> [c]]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM