Skip to content

Instantly share code, notes, and snippets.

@iammerrick
Created February 24, 2016 05:52
Show Gist options
  • Save iammerrick/58bcd46094674facaf7a to your computer and use it in GitHub Desktop.
Save iammerrick/58bcd46094674facaf7a to your computer and use it in GitHub Desktop.
In working through the third exercise on page 89 I am having trouble completing the task…
let x = 7; y = negate x; z = y * 10 in z / x + y
So my first take looks something like this:
(\x -> (\y -> (\z -> z / x + y) (y * 10)) negate x) 7
But it won’t compile so I start to pair it back… I notice I get a different error here:
(\x -> (\y -> (\z -> z) (y * 10)) negate x) 7
Something about the y * 10 has a type error
<interactive>:43:1:
Non type-variable argument in the constraint: Num (a -> a)
(Use FlexibleContexts to permit this)
When checking that ‘it’ has the inferred type
it :: forall a. (Num a, Num (a -> a)) => a
I really don’t understand what this is saying, the error doesn’t show the same variables as my code nor do I find the type declaration clear to read. (Hoping this comes with time and experience). The confusing thing is if I run
negate 7 * 10
I get the correct result but doing it in this lambda body has issues.
Anyways I am frustrated, (that’s ok though, it means I’m learning something new :-) any help would be appreciated.
Thanks!
Merrick
@seanhess
Copy link

exercise :: Int
exercise =
  (\x -> (\y -> (\z -> z) (y * 10)) (negate x)) 7

You forgot parentheses around negate x so it was trying to pass the negate function in where you thought you were passing a number, then x into what was left, leading to a very confusing error message.

@seanhess
Copy link

negate 7 * 10 works because of the precedence of the * operator. It acts like implicit parens, in the same way that 3 * 2 + 4 * 4 does.

@iammerrick
Copy link
Author

@seanhess thank you so much! This was so extremely helpful. I really don't understand the error message though:

Prelude> (\x -> (\y -> (\z -> z / x + y) (y * 10)) negate x) 7

<interactive>:3:50:
    Occurs check: cannot construct the infinite type: a ~ a -> a
    Relevant bindings include
      x :: a -> a (bound at <interactive>:3:3)
      it :: a (bound at <interactive>:3:1)
    In the second argument of ‘\ y
                                 -> (\ z -> z / x + y) (y * 10)’, namely
      ‘x’
    In the expression: (\ y -> (\ z -> z / x + y) (y * 10)) negate x

My mind wants something like "y is not a function" or something haha. Can you help me gain any insight into what the compiler is trying to tell me in that error message that might help me conclude I was passing a function instead of a number around?

@seanhess
Copy link

Well, it means that the compiler is very, very confused. I've only gotten that error once or twice. The compiler error would be lots better if your function was composed from smaller ones, each with a type signature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment