0
votes

Studying Haskell. Like it. Like the book, but stuck on types, typeclasses. given type declaration

co :: (b -> c) -> (a -> b) -> a -> c
co = undefined  -- (obviously)

Question in book: Design function (answer on GitHub)

co = ($)

Yes it compiles but

1) Why?

2) What does this function do and why does it typecheck as it does. Just want to understand rather than just remember.

1
co is a function that takes a function from b->c and returns a function that takes a function from a->b and returns a function that takes an a and returns a c. Meaning that you can define any function that matches that type signature.Jared Smith
No, it doesn't compile. See also difference between . and $.Daniel Wagner

1 Answers

3
votes

Yes it compiles but

It doesn't compile because it is not type correct:

/tmp/so.hs:2:6: error:
    • Couldn't match type ‘c’ with ‘a -> c’
      ‘c’ is a rigid type variable bound by
        the type signature for:
          co :: forall b c a. (b -> c) -> (a -> b) -> a -> c
        at /tmp/so.hs:1:1-36
      Expected type: (b -> c) -> (a -> b) -> a -> c
        Actual type: ((a -> b) -> a -> c) -> (a -> b) -> a -> c
    • In the expression: ($)
      In an equation for ‘co’: co = ($)
    • Relevant bindings include
        co :: (b -> c) -> (a -> b) -> a -> c (bound at /tmp/so.hs:2:1)
  |
2 | co = ($)

Informally, co's first argument is a function that transforms values of type b to values of type c. The second is a function that transforms values of type a to values of type b. The final argument is a value of type a. From here it is apparent you can apply the second argument to the third, obtaining a b and then apply the first argument, obtaining a value of type c.

So long as you understand the syntax of function application things should be apparent from here.