0

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.

David Young
  • 10,713
  • 2
  • 33
  • 47
Madderote
  • 1,107
  • 10
  • 19
  • 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 Sep 13 '17 at 17:52
  • 11
    No, it doesn't compile. See also [difference between . and $](https://stackoverflow.com/q/940382/791604). – Daniel Wagner Sep 13 '17 at 18:05

1 Answers1

3

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.

Thomas M. DuBuisson
  • 64,245
  • 7
  • 109
  • 166
  • Thanks a lot. I figured that I could do with studying types and typeclasses again, just to make sure I get the routine in. Thanks for answering this. Appreciate the help! – Madderote Sep 14 '17 at 19:26
  • Following your answer I distilled the following and it typechecks!!! co :: (b -> c) -> (a -> b) -> a -> c co = a where b = a c = b a = a – Madderote Sep 16 '17 at 18:16
  • @Madderote While that will typecheck, It won't evaluate to anything because you have defined `a` to be equal to itself and `co` to be equal to `a`. `a` being equal to itself means you have formed an infinite loop (or possibly an exception explaining it otherwise would be an infinite loop). – Potato44 Sep 17 '17 at 19:31