Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell "Non type-variable argument in the constraint"

I've created a list of partially applied functions in my REPL like so:

listOfPartiallyAppliedFunctions = map (*) [1..100]

I would then like to create the list of results from completing the function application, which I can easily do by providing a lambda to the map function like so:

let results = map (\x -> x 4) listOfPartiallyAppliedFunctions

Which basically means map the function x applied to 4 over the list of partially applied functions, where x is each partially applied function from the list.

However, I thought it would then follow that I could write:

let results = map (4) listOfPartiallyAppliedFunctions

As there shouldn't be a need to provide a lambda to the map function as it should know to apply 4 to the partially applied functions contained in the listOfPartiallyAppliedFunctions.

However, I am getting this error:

• Non type-variable argument in the constraint: Num ((a -> a) -> b)
  (Use FlexibleContexts to permit this)
• When checking the inferred type
    it :: forall a b. (Num a, Num ((a -> a) -> b), Enum a) => [b]

Can someone help me parse this error? I thought 4 was an instance of type constructor Num?

like image 740
Thomas Cook Avatar asked Jul 09 '19 14:07

Thomas Cook


2 Answers

However, I thought it would then follow that I could write:

let results = map (4) listOfPartiallyAppliedFunctions

No, if you would have performed \x -> 4 x, you could replace it with 4. But since 4 means it is a Num instance, and you likely did not make a function a -> b an instance of Num, the compiler can not solve this. The compiler thus says that it does not find a way to convert the number 4 into a function, and definitely not a function that takes as input a function Num a => a -> a, and then converts this to a b.

You can however write the above as just:

let results = map ($ 4) listOfPartiallyAppliedFunctions

Here we thus perform a sectioning of an infix operator [Haskell-wiki] on the ($) :: (a -> b) -> a -> b function.

like image 155
Willem Van Onsem Avatar answered Oct 29 '22 01:10

Willem Van Onsem


Three "laws" of operator sections are

(a `op` b)  =  (a `op`) b  =  (`op` b) a  =  op a b

(the missing argument goes into the free slot near the operator),

or with $,

a b  =  (a $ b)  =  (a $) b  =  ($ b) a  =  ($) a b

Thus

(\ x -> x 4) = (\ x -> x $ 4) = (\ x -> ($ 4) x)

and that, by eta-reduction, is

($ 4) 
like image 8
Will Ness Avatar answered Oct 29 '22 01:10

Will Ness