What does `Forky (a -> b) means in type declaration?

This is from some exercise:

(<*>) :: Forky (a -> b) -> Forky a -> Forky b

where Forky is defined as

data Forky a = Tip a | Branch (Forky a) (Forky a)
    deriving (Eq, Show)

Usually, I see (a -> b) as a function in the type declaration. But what does Forky (a -> b) means?

3 answers

  • answered 2018-07-11 02:59 Silvio Mayolo

    a -> b is a type like any other. Substituting it into the Forky declaration means that the first argument to your <*> operator will be either a Tip f (where f :: a -> b) or a Branch consisting of two Forky (a -> b). Forky (a -> b) is just like a Forky Int, except instead of containing integers at the leaves, it contains functions.

  • answered 2018-07-11 03:00 chepner

    a -> b is still a function type; here, the type constructor Forky is applied to it to get another type. Since Forky a is basically a type of binary trees containing a values, Forky (a -> b) is a tree containing functions.

    Note the similarities:

    data Forky a = Tip  a | Branch (Forky a) (Forky a)
    data Tree  a = Leaf a | Node   (Tree  a) (Tree  a)
    

  • answered 2018-07-11 19:13 luqui

    This is a list of three functions

    funcs :: [Int -> Int]
    funcs = [ abs, \x -> 2*x+1, (`mod` 16) ]
    

    Here's a function that maybe returns a function:

    adder :: Int -> Maybe (Int -> Int)
    adder n
        | n > 0 = Just (\m -> n + m)
        | otherwise = Nothing
    

    Here's a function that takes a maybe function as an argument:

    applyMay :: Maybe (a -> a) -> a -> a
    applyMay Nothing x = x
    applyMay (Just f) x = f x