简体   繁体   中英

Determining the type of a function in Functional Programming

The following equations are written in Miranda Syntax, but due to the similarities between Miranda and Haskell I expect Haskell programmers should understand it!

If you define the following functions:

rc v g i = g (v:i)
rn x = x
rh g = hd (g [])


f [] y = y 
f (x:xs) y = f xs (rc x y)

g [] y = y
g (x:xs) y = g xs (x:y)

How do you work out the type of the functions? I think I understand how to work it out for f,g and rn but I'm confused about the partial application part.

rn is going to be * -> * ( or anything -> anything, I think it's a -> a in Haskell? )

For f and g, are the function types both [*] -> * -> * ?

I'm unsure how to approach finding the types for rc and rh though. In rc, g is being partially applied to the variable i - so I'm guessing that this constrains the type of i to be [*]. What order are rc and g applied in the definition of rc? Is g applied to i, and then the resulting function used as the argument for rc? Or does rc take 3 separate parameters of v,g and i? I'm really confused.. any help would be appreciated! Thanks guys.

Sorry forgot to add that hd is the standard head function for a list and is defined as:

hd :: [*] -> *
hd (a:x) = a
hd [] = error "hd []"

The type is inferred from what is already known of types and how expressions are used in the definition.

Let's begin at the top,

rc v g i = g (v : i)

so rc :: a -> b -> c -> d and we must see what can be found out about a, b, c and d . On the right hand side, there appears (v : i) , so with v :: a , we see that i :: [a] , c = [a] . Then g is applied to v : i , so g :: [a] -> d , altogether,

rc :: a -> ([a] -> d) -> [a] -> d

rn x = x means that there's no constraint on the argument type of rn and its return type is the same, rn :: a -> a .

rh g = hd (g [])

Since rh 's argument g is applied to an empty list on the RHS, it must have type [a] -> b , possibly more information about a or b follows. Indeed, g [] is the argument of hd on the RHS, so g [] :: [c] and g :: [a] -> [c] , hence

rh :: ([a] -> [c]) -> c

Next

f [] y = y 
f (x:xs) y = f xs (rc x y)

The first argument is a list, and if that is empty, the result is the second argument, so f :: [a] -> b -> b follows from the first equation. Now, in the second equation, on the RHS, the second argument to f is rc xy , hence rc xy must have the same type as y , we called that b . But

rc :: a -> ([a] -> d) -> [a] -> d

, so b = [a] -> d . Hence

f :: [a] -> ([a] -> d) -> [a] -> d

Finally

g [] y = y
g (x:xs) y = g xs (x:y)

from the first equation we deduce g :: [a] -> b -> b . From the second, we deduce b = [a] , since we take the head of g 's first argument and cons it to the second, thus

g :: [a] -> [a] -> [a]

I'm going to use the haskell syntax to write types.

rc v g i = g (v:i)

Here rc takes three parameters, so its type will be something like a -> b -> c -> d . v:i must be a list of elements of the same type as v and i , so v :: a and i :: [a] . g is applied to that list, so that g :: [a] -> d . If you put all together, you get rc :: a -> ([a] -> d) -> [a] -> d .

As you already figured out rn :: a -> a , because it is simply the identity.

I have no idea about the type of the hd function you use in rh , so I'll skip that.

f [] y = y 
f (x:xs) y = f xs (rc x y)

Here f takes two parameters, so its type will be something like a -> b -> c . From the first case we can deduce that b == c , since we return y , and that the first argument is a list. For now we know that f :: [a'] -> b -> b . In the second case notice how x and y are given in input to rc : y must be a function [a'] -> d , and rc xy :: a' -> d (that must be also the type of y , since it is passed as it second argument of f ). Finally, we can say that f :: [a'] -> ([a'] -> d) -> ([a'] -> d) . Since -> is right-associative, this is equivalent to [a'] -> ([a'] -> d) -> [a'] -> d .

You can reason in the same manner for the remaining ones.

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