y = [\a->a+3, \b->1 , \c->c*c]
I recognize function y has type of [Integer->Integer] , implies that it return list of function and each function takes integer then return a integer. However, I have trouble figure out the input of the function , could someone give me an example?
There isn't any input. y does not expect any parameter, it will only provides a list of function of type Integer -> Integer (or more precisely: Num a => a -> a).
How can it be useful?
Well, you can use it in many ways, some examples:
>>> let y = [\a->a+3, \b->1 , \c->c*c]
>>> map (\f -> f 3) y
[6,1,9]
>>> sequence y 4
[7,1,16]
>>> head y 10
13
First, the actual type of y is Num a => [a -> a], because integer numbers are polymorphic constants.
Second, y is not a function, it is a list. It does not take any arguments; its elements do. Or, if you want to call it a function, it has 0 arguments and returns a list.
y is not a function, it's a list of functions.
There is no input. It's just a list of functions. You can pick one of these functions up and call it with some input, but as it stands, it's just a bunch of functions that have been put into a list.
Related
If i'm creating a function, let's take the simplest example:
add x y = x + y
if i want to add a Function Type declaration before, for clarity sake
add :: (Int, Int) -> Int
add x y = x + y
I get a compile error:
"Couldn't match expected type ‘Int’ with actual type ‘(Int, Int) -> (Int, Int)’".
"The equation(s) for ‘add’ have two arguments, but its type ‘(Int, Int) -> Int’ has only one"
but it compiles flawlessly if i correct it to
add :: (Int, Int) -> Int
add (x, y) = x + y
coming from other languages, i actually think it's clearer to use the second form with parenthesis, but in my opinion, both ways should work
1 - what is the reason for not working the first way?
2 - i find the error messages completely confusing so, maybe, the error happens for another reason i don't understand
what is the reason for not working the first way?
In the first expression your type says it takes a 2-tuple as single parameter, and it returns the sum of the two items. But in the "body" of the function, you specify add x y = x + y hence you construct a function that takes a parameter x that will return a function that will take a parameter y which maps to x + y.
In Haskell all functions take one parameter. Indeed, your add function takes one parameter x. It is short for:
add x = \y -> x + y
It thus returns a function that will take a parameter y and then maps y to x + y. If you thus construct a function f = add 2, then f will take the parameter y, and map this on 2 + y.
The arrow is a right-associative operator. This means that Int -> Int -> Int is short for Int -> (Int -> Int), it thus is a function that maps an Int to another function.
You can see the syntax of languages like Java where they call f (x, y) basically as calling the function f with one object: a 2-tuple with x and y as its two elements.
I am new to Haskell.
In Yet Another Haskell Tutorial, page Type Basics, I find this example:
count2 bTest list = foldr (\x cnt -> if bTest x then cnt+1 else cnt) 0 list
but I think that the lambda function
\x cnt -> if bTest x then cnt+1 else cnt
is not a pure function, given that its behavior depends on something external to the function, namely the function bTest. Is this correct?
Lambda abstractions are expressions which denote function values, much like arithmetic expressions denote numeric values. Both kinds of expressions might refer to variables defined elsewhere, and this does not break "purity"/referential transparency.
The value of the arithmetic expression
2*x + 1
depends on the value of x, but that does not make the above code "impure". Consider the function
f :: Int -> Int
f x = 2*x + 1
This produces the same output value for the same input value, so it it pure.
Now, consider the lambda expression
\y -> 2*x + y
This denotes a function value which depends on x, much like the arithmetic expression depends on x. There's no difference in this regard.
Indeed, the function
g :: Int -> (Int -> Int)
g x = \y -> 2*x + y
is pure: given the same x, it returns the same output value, which is a function. And, on top of that, the returned function is pure: given the same y, it returns the same numeric value. To stress the point
let h = g 5
in h 23 == h 23
evaluates to True since both h 23 evaluate to 2*5+23.
By comparison, this evaluates to False
let h1 = g 5
h2 = g 1
in h1 23 == h2 23
since we compare 2*5+23 against 2*1+23. This, however, does not break purity since h1 and h2 are different function values: we are not calling the same function with the same input, and that can indeed produce different results.
No this is not correct.
The lambda function returns the same output for the same input any time it is called, without any other effects.
To do that it does depend on the value of a parameter to the outer function, but that's just a detail.
In different invocations of count2 there might be used different values for bTest. In such situations the two lambda function will be different, yes, but the bTest values serve as a hidden implicit input. Still, the same inputs entailing the same output, which is the definition of "pure".
I want to calculate the "e" constant using Haskell's (Prelude) built-in until function. I want to do something like this:
enumber = until (>2.7) iter (1 0)
iter x k = x + (1/(fact (k + 1)))
fact k = foldr (*) 1 [1..k]
When I try to run this code, I get this error:
Occurs check: cannot construct the infinite type: a ~ a -> a
Expected type: (a -> a) -> a -> a
Actual type: a -> a -> a
Relevant bindings include enumber :: a -> a (bound at Lab2.hs:65:1)
In the second argument of ‘until’, namely ‘iter’
In the expression: until (> 2.7) iter (1 0)
By "e" I mean e = 2.71828..
The concrete mistake that causes this error is the notation (1 0). This doesn't make any sense in Haskell, it is parsed such that 1 is a function which is applied to 0, and the result then used. You apparently mean to pass both 1 and 0 as (initial) arguments. That's what we have tuples for, written (1,0).
Now, before trying to make anything definitions, we should make clear what types we need and write them out. Always start with your type signatures, they guide you a lot to you the actual definitions should look!
enumber :: Double -- could also be a polymorphic number type, but let's keep it simple.
type Index = Double -- this should, perhaps, actually be an integer, but again for simlicity use only `Double`
fact :: Index -> Double
now, if you want to do something like enumber = until (>2.7) iter (1,0), then iter would need to both add up the series expansion, and increment the k index (until knows nothing about indices), i.e. something like
iter :: (Double, Index) -> (Double, Index)
But right now your iter has a signature more like
iter :: Double -> Index -> Double
i.e. it does not do the index-incrementing. Also, it's curried, i.e. doesn't accept the arguments as a tuple.
Let's try to work with a tuple signature:
iter :: (Double, Index) -> (Double, Index)
iter (x,k) = ( x + 1/(fact (k + 1)), k+1 )
If you want to use this with until, you have the problem that you're always working with tuples, not just with the accumulated results. You need to throw away the index, both in the termination condition and in the final result: this can easily be done with the fst function
enumber = fst $ until ((>2.7) . fst) iter (1,0)
Now, while this version of the code will type-check, it's neither elegant nor efficient nor accurate (being greater than 2.7 is hardly a meaningful condition here...). As chi remarks, a good way of summing up stuff is the scanl function.
Apart from avoiding to manually increment and pass around an index, you should also avoid calculating the entire factorial over and over again. Doing that is a pretty general code smell (there's a reason fact isn't defined in the standard libraries)
recipFacts :: [Double] -- Infinite list of reciprocal factorials, starting from 1/0!
recipFacts = go 1
where go k = 1 : map (/k) (go (k+1))
Incidentally, this can also be written as a scan: scanl (/) 1 [1..] (courtesy of Will Ness).
Next we can use scanl to calculate the partial sums, and use some termination condition. However, because the series converges so quickly, there's actually a hack that works fine and is even simpler:
enumber :: Double
enumber = sum $ takeWhile (>0) recipFacts
-- result: 2.7182818284590455
Here I've used the fact that the fast-growing factorial quickly causes the floating-point reciprocals to underflow to zero.
Of course, really there's not a need to sum anything up yourself at all here: the most to-the-point definition is
enumber = exp 1
and nothing else.
enumber = until (>2.7) iter (1 0)
-- ^^^^^
Above you are applying "function" 1 to argument 0. This can't work.
You may want to use a pair instead (1, 0). In that case, not that iter must be changed to accept and return a pair. Also, the predicate >2.7 must be adapted to pairs.
If you don't want to use pairs, you need a different approach. Look up the scanl function, which you can use to compute partial sums. Then, you can use dropWhile to discard partial sums until some good-enough predicate is satisfied.
An example: the first ten partial sums of n^2.
> take 10 $ scanl (+) 0 [ n^2 | n<-[1..] ]
[0,1,5,14,30,55,91,140,204,285]
Note that this approach works only if you compute all the list elements independently. If you want to reuse some computed value from one element to another, you need something else. E.g.
> take 10 $ snd $ mapAccumL (\(s,p) x -> ((s+p,p*2),s+p)) (0,1) [1..]
[1,3,7,15,31,63,127,255,511,1023]
Dissected:
mapAccumL (\(s,p) x -> ((s+p,p*2),s+p)) (0,1) [1..]
a b c d e
s previous sum
p previous power of two
x current element of [1..]
a next sum
b next power of two
c element in the generated list
d first sum
e first power of two
Still, I am not a big fan of mapAccumL. Using iterate and pairs looks nicer.
I am trying to understand currying by reading various blogs and stack over flow answers and I think I understood some what. In Haskell, every function is curried, it means, when you have a function like f x y = x + y
it really is ((f x) y)
in this, the function initially take the first parameter 'x' as the parameter and partially applies it to function f which in turn returns a function for y. where it takes just y a single parameter and applies the function. In both cases the function takes only one parameter and also the process of reducing a function to take single parameter is called 'currying'. Correct me if my understanding wrong here.
So if it is correct, could you please tell me if the functions 'two' and 'three' are curried functions?
three x y z = x + y + z
two = three 1
same = two 1
In this case, I have two specialized functions, 'two' and 'same' which are reduced to take only one parameter so is it curried?
Let's look at two first.
It has a signature of
two :: Num a => a -> a -> a
forget the Num a for now (it's only a constraint on a - you can read Int here).
Surely this too is a curried function.
The next one is more interesting:
same :: Num a => a -> a
(btw: nice name - it's the same but not exactly id ^^)
TBH: I don't know for sure.
The best definition I know of a curried function is this:
A curried function is a function of N arguments returning another function of (N-1) arguments.
(if you want you can extent this to fully curried functions of course)
This will only fit if you define constants as functions with 0 parameters - which you surely can.
So I would say yes(?) this too is a curried function but only in a mathy borderline way (like the sum of 0 numbers is defined to be 0)
Best just think about this equationally. The following are all equivalent definitions:
f x y z = x+y+z
f x y = \z -> x+y+z
f x = \y -> (\z -> x+y+z)
f = \x -> (\y -> (\z -> x+y+z))
Partial application is only tangentially relevant here. Most often you don't want the actual partial application to be performed and the actual lambda object to be created in memory - hoping instead that the compiler will employ - and optimize better - the full definition at the final point of full application.
The presence of the functions curry/uncurry is yet another confusing issue. Both f (x,y) = ... and f x y = ... are curried in Haskell, of course, but in our heads we tend to think about the first as a function of two arguments, so the functions translating between the two forms are named curry and uncurry, as a mnemonic.
You could think that three function with anonymous functions is:
three = \x -> (\y -> (\z -> x + y + z)))
I'm very new to haskell, writing a simple code that returns how many inputs are larger than their average value. I got error:
ERROR file:.\AverageThree.hs:5 - Type error in application
* Expression : x y z
Term : x
Type : Int
* Does not match : a -> b -> c
Code:
averageThree :: Int -> Int -> Int -> Float
averageThree x y z = (fromIntegral x+ fromIntegral y+ fromIntegral z)/3
howManyAverageThree ::Int -> Int -> Int -> Int
howManyAverageThree x y z = length > averageThree
Anyone help me?
The trouble you're having comes from a few places.
First, you aren't applying either function, length or averageThree - and hence also not using your arguments to howManyAverageThree.
Second, the type of length is [a] -> Int. As you don't have a list here, you either have to use a different function, or make a list.
If I understand your desired algorithm correctly, you are going to need to do a few things:
Apply x y and z to averageThree.
Use the filter function, comparing this computed average with each passed in parameter; this will result in a list.
Find the length of the resulting list.
The code I dashed off to do this follows:
howManyAverageThree ::Int -> Int -> Int -> Int
howManyAverageThree x y z = length $ filter (> avg) the_three
where avg = averageThree x y z
the_three = [fromIntegral x,fromIntegral y,fromIntegral z]
This takes advantage of a couple of neat features:
Currying, sometimes called "partial function application". That's what I was using with (> avg); normally, the infix function > takes two parameters of the same type, and returns a Bool - by wrapping in parenthesis and providing an expression on one side, I have partially applied it, which allows it to be used as a filter function
The where keyword. I used this to clean it all up a little and make it more readable.
The filter function, which I mentioned above.
Function application using $. This operator just changes the function application from left-associative to right-associative.
There are a number of problems here:
length doesn't do what you want it to. length returns the length of a list, and there are no lists in your howManyAvergageThree
averageThree returns a Float. howManyAverageThree needs to account for that. Specifically, > needs its arguments to be of the same type.
The call to averageThree in the second function needs some arguments.
Here's a working version:
howManyAverageThree x y z = length [ i | i <- [x, y, z], fromIntegral i > avg]
where avg = averageThree x y z