I am new to Haskell, using Ghci.
I have a function, called three, that I want to write as
let three = \x->(\y->(x(x(x y))))
OK, this works, but when I try
three (2+) 4
It does not work. Instead, I get some "cannot construct infinite type" error.
Please help me.
ghci> let three = \x->(\y->(x(x(x y))))
ghci> three (2+) 4
10
ghci> three return "deconstructivist"
<interactive>:1:6:
Occurs check: cannot construct the infinite type: t = m t
Expected type: t
Inferred type: m t
In the first argument of 'three', namely 'return'
In the expression: three return "deconstructivist"
ghci> :t three
three :: (t -> t) -> t -> t
ghci> :t return
return :: (Monad m) => a -> m a
The example you supplied of three (2+) 4, works! Better check that the examples you provide actually reproduce your problem.
As for with a different example, like the one above with return, the thing is that return results in a different type than the one given. If the type was the same, it would be infinite (and of kind * -> * -> * -> ...), which Haskell does not support.
The example you give does work. Let's explain why:
three f = f . f . f
-- so...
three :: (a -> a) -> a -> a
The function needs to have type a -> a because it will receive it's own argument, which requires a type. (2+) has type Num a => a -> a, so three (2+) 4 will work just fine.
However, when you pass a function like return of type Monad m => a -> m a, which returns a different type, it will not match the (a -> a) requirement we set out. This is where and when your function will fail.
While you're at it, try making a function like doTimes with type Integer -> (a -> a) -> a -> a which does the given function the given number of times - it's a good next step after making this function.
Related
I understand that the $ operator is for avoiding parentheses. Anything appearing after it will take precedence over anything that comes before.
I am trying to understand what it means in this context:
map ($ 3) [(+),(-),(/),(*)]
With the following code:
instance Show (a -> b) where
show a = function
main = putStrLn $ show $ map ($ 3) [(+),(-),(/),(*)]
The output is
["function", "function", "function", "function"]
This doesn't help me understand the meaning of the $ here.
How can I display more helpful output?
($) :: (a -> b) -> a -> b is a function that takes a function as first parameter, and a value as second and returns the value applied to that function.
For example:
Prelude> (1+) $ 2
3
The expression ($ 3) is an example of infix operator sectioning [Haskell-wiki]. ($ 3) is short for \f -> f $ 3, or simpler \f -> f 3. It thus is a function that takes a function and applies 3 to that function.
For your expression:
map ($ 3) [(+),(-),(/),(*)]
the output is thus equivalent to:
[(3+), (3-), (3/), (3*)] :: Fractional a => [a -> a]
Since (+), (-), (*) :: Num a => a -> a -> a work with types that are members of the Num typeclass, and (/) :: Fractional a => a -> a -> a works with types that are members of the Fractional type class, and all Fractional types are num types as well, 3 is here a Fractional type, and the list thus contains functions that are all of the type a -> a with a a member of Fractional.
How can I display more helpful output?
The compiler does not keep track of the expressions, as specified in the Haskell wiki page on Show instance for functions [Haskell-wiki].
The Haskell compiler doesn't maintain the expressions as they are, but translates them to machine code or some other low-level representation. The function \x -> x - x + x :: Int -> Int might have been optimized to \x -> x :: Int -> Int. If it's used anywhere, it might have been inlined and optimized to nothing. The variable name x is not stored anywhere. (...)
So we can not "look inside" the function and derive an expression that is human-readable.
Is there a way in haskell to get all function arguments as a list.
Let's supose we have the following program, where we want to add the two smaller numbers and then subtract the largest. Suppose, we can't change the function definition of foo :: Int -> Int -> Int -> Int. Is there a way to get all function arguments as a list, other than constructing a new list and add all arguments as an element of said list? More importantly, is there a general way of doing this independent of the number of arguments?
Example:
module Foo where
import Data.List
foo :: Int -> Int -> Int -> Int
foo a b c = result!!0 + result!!1 - result!!2 where result = sort ([a, b, c])
is there a general way of doing this independent of the number of arguments?
Not really; at least it's not worth it. First off, this entire idea isn't very useful because lists are homogeneous: all elements must have the same type, so it only works for the rather unusual special case of functions which only take arguments of a single type.
Even then, the problem is that “number of arguments” isn't really a sensible concept in Haskell, because as Willem Van Onsem commented, all functions really only have one argument (further arguments are actually only given to the result of the first application, which has again function type).
That said, at least for a single argument- and final-result type, it is quite easy to pack any number of arguments into a list:
{-# LANGUAGE FlexibleInstances #-}
class UsingList f where
usingList :: ([Int] -> Int) -> f
instance UsingList Int where
usingList f = f []
instance UsingList r => UsingList (Int -> r) where
usingList f a = usingList (f . (a:))
foo :: Int -> Int -> Int -> Int
foo = usingList $ (\[α,β,γ] -> α + β - γ) . sort
It's also possible to make this work for any type of the arguments, using type families or a multi-param type class. What's not so simple though is to write it once and for all with variable type of the final result. The reason being, that would also have to handle a function as the type of final result. But then, that could also be intepreted as “we still need to add one more argument to the list”!
With all respect, I would disagree with #leftaroundabout's answer above. Something being
unusual is not a reason to shun it as unworthy.
It is correct that you would not be able to define a polymorphic variadic list constructor
without type annotations. However, we're not usually dealing with Haskell 98, where type
annotations were never required. With Dependent Haskell just around the corner, some
familiarity with non-trivial type annotations is becoming vital.
So, let's take a shot at this, disregarding worthiness considerations.
One way to define a function that does not seem to admit a single type is to make it a method of a
suitably constructed class. Many a trick involving type classes were devised by cunning
Haskellers, starting at least as early as 15 years ago. Even if we don't understand their
type wizardry in all its depth, we may still try our hand with a similar approach.
Let us first try to obtain a method for summing any number of Integers. That means repeatedly
applying a function like (+), with a uniform type such as a -> a -> a. Here's one way to do
it:
class Eval a where
eval :: Integer -> a
instance (Eval a) => Eval (Integer -> a) where
eval i = \y -> eval (i + y)
instance Eval Integer where
eval i = i
And this is the extract from repl:
λ eval 1 2 3 :: Integer
6
Notice that we can't do without explicit type annotation, because the very idea of our approach is
that an expression eval x1 ... xn may either be a function that waits for yet another argument,
or a final value.
One generalization now is to actually make a list of values. The science tells us that
we may derive any monoid from a list. Indeed, insofar as sum is a monoid, we may turn arguments to
a list, then sum it and obtain the same result as above.
Here's how we can go about turning arguments of our method to a list:
class Eval a where
eval2 :: [Integer] -> Integer -> a
instance (Eval a) => Eval (Integer -> a) where
eval2 is i = \j -> eval2 (i:is) j
instance Eval [Integer] where
eval2 is i = i:is
This is how it would work:
λ eval2 [] 1 2 3 4 5 :: [Integer]
[5,4,3,2,1]
Unfortunately, we have to make eval binary, rather than unary, because it now has to compose two
different things: a (possibly empty) list of values and the next value to put in. Notice how it's
similar to the usual foldr:
λ foldr (:) [] [1,2,3,4,5]
[1,2,3,4,5]
The next generalization we'd like to have is allowing arbitrary types inside the list. It's a bit
tricky, as we have to make Eval a 2-parameter type class:
class Eval a i where
eval2 :: [i] -> i -> a
instance (Eval a i) => Eval (i -> a) i where
eval2 is i = \j -> eval2 (i:is) j
instance Eval [i] i where
eval2 is i = i:is
It works as the previous with Integers, but it can also carry any other type, even a function:
(I'm sorry for the messy example. I had to show a function somehow.)
λ ($ 10) <$> (eval2 [] (+1) (subtract 2) (*3) (^4) :: [Integer -> Integer])
[10000,30,8,11]
So far so good: we can convert any number of arguments into a list. However, it will be hard to
compose this function with the one that would do useful work with the resulting list, because
composition only admits unary functions − with some trickery, binary ones, but in no way the
variadic. Seems like we'll have to define our own way to compose functions. That's how I see it:
class Ap a i r where
apply :: ([i] -> r) -> [i] -> i -> a
apply', ($...) :: ([i] -> r) -> i -> a
($...) = apply'
instance Ap a i r => Ap (i -> a) i r where
apply f xs x = \y -> apply f (x:xs) y
apply' f x = \y -> apply f [x] y
instance Ap r i r where
apply f xs x = f $ x:xs
apply' f x = f [x]
Now we can write our desired function as an application of a list-admitting function to any number
of arguments:
foo' :: (Num r, Ord r, Ap a r r) => r -> a
foo' = (g $...)
where f = (\result -> (result !! 0) + (result !! 1) - (result !! 2))
g = f . sort
You'll still have to type annotate it at every call site, like this:
λ foo' 4 5 10 :: Integer
-1
− But so far, that's the best I can do.
The more I study Haskell, the more I am certain that nothing is impossible.
I'm still a beginner when it comes to Haskell syntax and functional programming languages so when I look at the type declaration for Data.Function.on which is on :: (b -> b -> c) -> (a -> b) -> a -> a -> c, my interpretation is that it takes four parameters: (b -> b -> c), (a -> b), a, a, and returns c. However, when I look at the general use syntax for Data.Function.on which is (*) `on` f = \x y -> f x * f y, it is only taking two function parameters, not four, so how does the type signature relate to the usage syntax?
my interpretation is that it takes four parameters
All Haskell functions take one argument. Some of them just return other functions.
The best way to look at the signature for on is as a higher-order function: (b -> b -> c) -> (a -> b) -> (a -> a -> c). This says "if you give me a binary operator that takes bs and gives a c and a way to get bs from as, I will give you a binary operator that takes as and gives a c". You can see this in the definition:
(*) `on` f = \x y -> f x * f y
The Haskell arrow for function types hides a simple but clever idea. You have to think of -> as an operator, like + and -, but for types. It takes two types as arguments and gives you a new type consisting of a function. So in
Int -> String
You have the types Int and String, and you get a function from an Int to a String.
Just like any other operator, you need a rule for a chain of them. If you think of -, what does this mean?
10 - 6 - 4
Does it mean (10 - 6) - 4 = 0, or does it mean 10 - (6 - 4) = 8? The answer is the first one, which is why we say that - is "left associative".
The -> operator is right associative, so
foo :: Int -> String -> String
actually means
foo :: Int -> (String -> String)
Think about what this means. It means that foo doesn't take 2 arguments and return a result of type String, it actually takes 1 argument (the Int) and returns a new function that takes the second argument (the String) and returns the final String.
Function application works the same way, except that is left associative. So
foo 15 "wibble"
actually means
(foo 15) "wibble"
So foo is applied to 15 and returns a new function which is then applied to "wibble".
This leads to a neat trick: instead of having to provide all the parameters when you call a function (as you do in just about every other programming language), you can just provide the first one or the first few, and get back a new function that expects the rest of the parameters.
This is what is happening with on. I'll use a more concrete version where 'f' is replaced by 'length'.
(*) on length
you give on its first two parameters. The result is a new function that expects the other two. In types,
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c
In this case (*) has type Num n => n -> n -> n (I'm using different letters to make this less confusing), so that is matched with the type of the first argument to on, leading to the conclusion that if type b is substitued by n then type c must be as well, and and must also be a Num instance. Therefore length must return some numeric type. As it happens the type of length is [d] -> Int, and Int is an instance of Num, so that works out. So at the end of this you get:
(*) `on` length :: [d] -> [d] -> Int
As an intuitive aid, I read this as "if you give me a comparator of type b, and a way to extract values of type b from values of type a, I will give you a comparator of type a".
E.g. if a is some composite data type and b is some numerical attribute of these data values, you can express the idea of sorting these composite data types by using Data.Function.on.
All the experiments described below were done with GHC 8.0.1.
This question is a follow-up to RankNTypes with type aliases confusion. The issue there boiled down to the types of functions like this one...
{-# LANGUAGE RankNTypes #-}
sleight1 :: a -> (Num a => [a]) -> a
sleight1 x (y:_) = x + y
... which are rejected by the type checker...
ThinAir.hs:4:13: error:
* No instance for (Num a) arising from a pattern
Possible fix:
add (Num a) to the context of
the type signature for:
sleight1 :: a -> (Num a => [a]) -> a
* In the pattern: y : _
In an equation for `sleight1': sleight1 x (y : _) = x + y
... because the higher-rank constraint Num a cannot be moved outside of the type of the second argument (as would be possible if we had a -> a -> (Num a => [a]) instead). That being so, we end up trying to add a higher-rank constraint to a variable already quantified over the whole thing, that is:
sleight1 :: forall a. a -> (Num a => [a]) -> a
With this recapitulation done, we might try to simplify the example a bit. Let's replace (+) with something that doesn't require Num, and uncouple the type of the problematic argument from that of the result:
sleight2 :: a -> (Num b => b) -> a
sleight2 x y = const x y
This doesn't work just like before (save for a slight change in the error message):
ThinAir.hs:7:24: error:
* No instance for (Num b) arising from a use of `y'
Possible fix:
add (Num b) to the context of
the type signature for:
sleight2 :: a -> (Num b => b) -> a
* In the second argument of `const', namely `y'
In the expression: const x y
In an equation for `sleight2': sleight2 x y = const x y
Failed, modules loaded: none.
Using const here, however, is perhaps unnecessary, so we might try writing the implementation ourselves:
sleight3 :: a -> (Num b => b) -> a
sleight3 x y = x
Surprisingly, this actually works!
Prelude> :r
[1 of 1] Compiling Main ( ThinAir.hs, interpreted )
Ok, modules loaded: Main.
*Main> :t sleight3
sleight3 :: a -> (Num b => b) -> a
*Main> sleight3 1 2
1
Even more bizarrely, there seems to be no actual Num constraint on the second argument:
*Main> sleight3 1 "wat"
1
I'm not quite sure about how to make that intelligible. Perhaps we might say that, just like we can juggle undefined as long as we never evaluate it, an unsatisfiable constraint can stick around in a type just fine as long as it is not used for unification anywhere in the right-hand side. That, however, feels like a pretty weak analogy, specially given that non-strictness as we usually understand it is a notion involving values, and not types. Furthermore, that leaves us no closer from grasping how in the world String unifies with Num b => b -- assuming that such a thing actually happens, something which I'm not at all sure of. What, then, is an accurate description of what is going on when a constraint seemingly vanishes in this manner?
Oh, it gets even weirder:
Prelude> sleight3 1 ("wat"+"man")
1
Prelude Data.Void> sleight3 1 (37 :: Void)
1
See, there is an actual Num constraint on that argument. Only, because (as chi already commented) the b is in a covariant position, this is not a constraint you have to provide when calling sleight3. Rather, you can just pick any type b, then whatever it is, sleight3 will provide a Num instance for it!
Well, clearly that's bogus. sleight3 can't provide such a num instance for strings, and most definitely not for Void. But it also doesn't actually need to because, quite like you said, the argument for which that constraint would apply is never evaluated. Recall that a constrained-polymorphic value is essentially just a function of a dictionary argument. sleight3 simply promises to provide such a dictionary before it actually gets to use y, but then it doesn't use y in any way, so it's fine.
It's basically the same as with a function like this:
defiant :: (Void -> Int) -> String
defiant f = "Haha"
Again, the argument function clearly can not possibly yield an Int because there doesn't exist a Void value to evaluate it with. But this isn't needed either, because f is simply ignored!
By contrast, sleight2 x y = const x y does kinda sorta use y: the second argument to const is just a rank-0 type, so the compiler needs to resolve any needed dictionaries at that point. Even if const ultimately also throws y away, it still “forces” enough of this value to make it evident that it's not well-typed.
I know that infinite sequences are possible in Haskell - however, I'm not entirely sure how to generate one
Given a method
generate::Integer->Integer
which take an integer and produces the next integer in the sequence, how would I build an infinite sequence out of this?
If you want your sequence to start from 1 then it is -
iterate generate 1
Please notice that first letter of function is lowercase, not uppercase. Otherwise it would be data type, not function.
//edit: I just realized not just data types start with capital, it could be data constructor or type class as well, but that wasn't the point. :)
Adding to Matajon's answer: a way to discover the iterate function other than asking here would be to use Hoogle.
Hoogle's first answer for the query (a -> a) -> [a] is iterate.
Update (2023): Hoogle's scoring appears to have changed and iterate is no longer given with this query. It's full type has another a parameter and with the full type it is given in the results.
There are several ways to do it, but one is:
gen :: (a -> a) -> a -> [a]
gen f s = s : gen f (f s)
This function takes a functon f and some valus s and returns s, after wich it calls itself with that same f, and the result of f s. Demonstration:
Prelude> :t succ
succ :: (Enum a) => a -> a
Prelude> let gen f s = s : gen f (f s)
Prelude> take 10 $ gen succ 3
[3,4,5,6,7,8,9,10,11,12]
In the above example succ acts as the function generate :: Integer -> Integer which you mention. But observe that gen will work with any function of type a -> a.
Edit: and indeed, gen is identical to the function iterate from the Prelude (and Data.List).