Skip to content

Instantly share code, notes, and snippets.

@bitemyapp
Last active March 3, 2016 07:57
Show Gist options
  • Save bitemyapp/c27c721b92dab0248433 to your computer and use it in GitHub Desktop.
Save bitemyapp/c27c721b92dab0248433 to your computer and use it in GitHub Desktop.
(\x -> (\y -> (\z -> z) (y * 10)) negate x) 7
-- apply x to 7, substituting 7 in for x. This value won't be relevant though.
(\y -> (\z -> z) (y * 10)) negate 7)
-- apply y to negate, substituting negate in for y
((\z -> z) (negate * 10)) 7
-- (\z -> z) is identity, so it's just (negate * 10)
(negate * 10) 7
-- the real issue is multiplying a function by a number as if a function was a number
Prelude> negate * 10
<interactive>:18:1: error:
• Non type-variable argument in the constraint: Num (a -> a)
(Use FlexibleContexts to permit this)
• When checking the inferred type
it :: forall a. (Num (a -> a), Num a) => a -> a
Prelude> :t negate
negate :: Num a => a -> a
When you pass negate :: Num a => a -> a
as an argument to
(*) :: Num a => a -> a -> a
which as two arguments of type
Num a => a
You are asking for a Num instance of type Num a => (a -> a)
The real problem is having tried to use anything of type (->) as a Num _ at all _, but the type checking short-circuits on an irrelevant issue with (a -> a) not being a generic enough type for a typeclass constraint, so it complains about Flexible Contexts instead.
You can reproduce this sort of Flexible Contexts thing like so:
Prelude> instance Eq (a -> a) where (==) = undefined
<interactive>:21:10: error:
• Illegal instance declaration for ‘Eq (a -> a)’
Note it's totally fine with:
Prelude> instance Eq (a -> b) where (==) = undefined
Prelude>
It's a rule about the type variables under a typeclass instance that most users won't have to think about usually.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment