As an exercise I'm trying to implement interesting parts of the prelude manually. Whenever I spot an opportunity to go point free I take it. However this has led me to a brick wall in the most unlikely place. Using this code:
myelem _ [] = False
myelem x y = if x == head y then True else myelem x (tail y)
I am trying to implement notElem. Here are my attempts:
-- First
mynotelem = not myelem
Understandably blows up due to the types not matching up. This is easily fixed:
-- Second
mynotelem x y = not (myelem x y)
However the explicit declaration of arguments x and y feels ugly and unnecessary, so I try to get it back into point free style.
-- Third
mynotelem = not $ myelem
Which fails with
Couldn't match expected type `Bool'
with actual type `a0 -> [a0] -> Bool'
In the second argument of `($)', namely `myelem'
In the expression: not $ myelem
In an equation for `mynotelem': mynotelem = not $ myelem
Fair enough, the types still don't match up. But how do you fix it? Again you can jump straight to
-- Fourth
mynotelem x y = not $ myelem x y
Which works, but seems dangerously close to just going in circles. I discover it's possible to eliminate one of the arguments:
-- Fifth
mynotelem x = not . (myelem x)
But that pesky x still remains. How do I eliminate it?
We can rewrite your code like this:
mynotelem x = not . (myelem x)
= (not .) (myelem x)
Now recognize that this is just h x = f (g x) with f = (not .) and g = myelem, so we can write it point-free with another use of the (.) operator as h = f . g:
mynotelem = (not .) . myelem
Note how the pattern continues when composing with functions with more arguments:
> let f x y z = x+y+z
> (((sqrt .) .) . f) 1 2 3
2.449489742783178
Alternatively, you can also write it with this funny-looking composition of composition operators:
mynotelem = ((.).(.)) not myelem
For more arguments, the pattern continues like this:
> ((.).(.).(.)) sqrt f 1 2 3
2.449489742783178
Related
Why does computing the following expression terminate?
foldr (\x t -> if x > 5 then Just x else t) Nothing $ [1..]
Is there anything special about Maybe (or one of the type classes it implements) that causes evaluation to stop after the lambda returns a Just?
Maybe ,Just, and Nothing play no active role here. What we see is just laziness at work. Indeed, for any (total) function f and value a, this would also terminate:
foldr (\x t -> if x > 5 then f x else t) a $ [1..]
This is perfectly equivalent to the plain recursion
foo [] = a
foo (x:xs) = if x > 5 then f x else foo xs
when called as foo [1..]. Eventually, x becomes 6, f 6 is returned, and no more recursive calls are made.
I wrote a function for evaluating a polynomial at a given number. The polynomial is represented as a list of coefficients (e.g. [1,2,3] corresponds to x^2+2x+3).
polyEval x p = sum (zipWith (*) (iterate (*x) 1) (reverse p))
As you can see, I first used a lot of parenthesis to group which expressions should be evaluated. For better readability I tried to eliminate as many parenthesis using . and $. (In my opinion more than two pairs of nested parenthesis are making the code more and more difficult to read.) I know that function application has highest priority and is left associative. The . and $are both right associative but . has priority 9, while $ has priority 0.
So it seemed to me that following expression cannot be written with even fewer parenthesis
polyEval x p = sum $ zipWith (*) (iterate (*x) 1) $ reverse p
I know that we need parenthesis for (*) and (*x) to convert them to prefix functions, but is it possible to somehow remove the parenthesis around iterate (*x) 1?
Also what version would you prefer for readability?
I know that there are many other ways to achieve the same, but I'd like to discuss my particular example, as it has a function evaluated in two arguments (iterate (*x) 1) as middle argument of another function that takes three arguments.
As usual with this sort of question I prefer the OP's version to any of the alternatives that have been proposed so far. I would write
polyEval x p = sum $ zipWith (*) (iterate (* x) 1) (reverse p)
and leave it at that. The two arguments of zipWith (*) play symmetric roles in the same way that the two arguments of * do, so eta-reducing is just obfuscation.
The value of $ is that it makes the outermost structure of the computation clear: the evaluation of a polynomial at a point is the sum of something. Eliminating parentheses should not be a goal in itself.
So it might be a little puerile, but I actually really like to think of Haskell’s rules in terms of food. I think of Haskell’s left-associative function application f x y = (f x) y as a sort of aggressive nom or greedy nom, in that the function f refuses to wait for the y to come around and immediately eats the f, unless you take the time to put these things in parentheses to make a sort of "argument sandwich" f (x y) (at which point the x, being uneaten, becomes hungry and eats the y.) The only boundaries are the operators and the special forms.
Then within the boundaries of the special forms, the operators consume whatever is around them; finally the special forms take their time to digest the expressions around them. This is the only reason that . and $ are able to save some parentheses.
Finally this we can see that iterate (* x) 1 is probably going to need to be in a sandwich because we don't want something to just eat iterate and stop. So there is no great way to do that without changing that code, unless we can somehow do away with the third argument to zipWith -- but that argument contains a p so that requires writing something to be more point-free.
So, one solution is to change your approach! It makes a little more sense to store a polynomial as a list of coefficients in the already-reversed direction, so that your x^2 + 2 * x + 3 example is stored as [3, 2, 1]. Then we don't need to perform this complicated reverse operation. It also makes the mathematics a little simpler as the product of two polynomials can be rewritten recursively as (a + x * P(x)) * (b + x * Q(x)) which gives the straightforward algorithm:
newtype Poly f = Poly [f] deriving (Eq, Show)
instance Num f => Num (Poly f) where
fromInteger n = Poly [fromInteger n]
negate (Poly ps) = Poly (map negate ps)
Poly f + Poly g = Poly $ summing f g where
summing [] g = g
summing f [] = f
summing (x:xs) (y:ys) = (x + y) : summing xs ys
Poly (x : xs) * Poly (y : ys) = prefix (x*y) (y_p + x_q) + r where
y_p = Poly $ map (y *) xs
x_q = Poly $ map (x *) ys
prefix n (Poly m) = Poly (n : m)
r = prefix 0 . prefix 0 $ Poly xs * Poly ys
Then your function
evaluatePoly :: Num f => Poly f -> f -> f
evaluatePoly (Poly p) x = eval p where
eval = (sum .) . zipWith (*) $ iterate (x *) 1
lacks parentheses around iterate because the eval is written in pointfree style, so $ can be used to consume the rest of the expression. As you can see it unfortunately leaves some new parentheses around (sum .) to do this, though, so it might not be totally worth your while. I find the latter less readable than, say,
evaluatePoly (Poly coeffs) x = sum $ zipWith (*) powersOfX coeffs where
powersOfX = iterate (x *) 1
I might even prefer to write the latter, if performance on high powers is not super-critical, as powersOfX = [x^n | n <- [0..]] or powersOfX = map (x^) [0..], but I think iterate is not too hard to understand in general.
Perhaps breaking it down to more elementary functions will simplify further. First define a dot product function to multiply two arrays (inner product).
dot x y = sum $ zipWith (*) x y
and change the order of terms in polyEval to minimize the parenthesis
polyEval x p = dot (reverse p) $ iterate (* x) 1
reduced to 3 pairs of parenthesis.
Consider the following situation. I define a function to process a list of elements by the typical way of doing an operation on the head and recalling the function over the rest of the list. But under certain condition of the element (being negative, being a special character, ...) I change sign on the rest of the list before continuing. Like this:
f [] = []
f (x : xs)
| x >= 0 = g x : f xs
| otherwise = h x : f (opposite xs)
opposite [] = []
opposite (y : ys) = negate y : opposite ys
As opposite (opposite xs) = xs, I become to the situation of redundant opposite operations, accumulating opposite . opposite . opposite ....
It happens with other operations instead of opposite, any such that the composition with itself is the identity, like reverse.
Is it possible to overcome this situation using functors / monads / applicatives / arrows? (I don't understand well those concepts). What I would like is to be able of defining a property, or a composition pattern, like this:
opposite . opposite = id -- or, opposite (opposite y) = y
in order that the compiler or interpreter avoids to calculate the opposite of the opposite (it is possible and simple (native) in some concatenative languages).
You can solve this without any monads, since the logic is quite simple:
f g h = go False where
go _ [] = []
go b (x':xs)
| x >= 0 = g x : go b xs
| otherwise = h x : go (not b) xs
where x = (if b then negate else id) x'
The body of the go function is almost identical to that of your original f function. The only difference is that go decides whether the element should be negated or not based on the boolean value passed to it from previous calls.
Sure, just keep a bit of state telling whether to apply negate to the current element or not. Thus:
f = mapM $ \x_ -> do
x <- gets (\b -> if b then x_ else negate x_)
if x >= 0
then return (g x)
else modify not >> return (h x)
I wrote a function to check if a list matches a condition, and if it does, it prints that value twice. However, in ghc it gives me an error, and i don't understand why...
verifyList f xs = foldl(\x acc -> if f x then x:x:acc else acc) [] xs
Any Help?
Looks like you meant foldr instead of foldl. If I make that change then it works for me.
You could also have done this without folds as
verifyList f xs = concatMap (\x -> [x, x]) $ filter f xs
which I would say more clearly indicates your intent. First filter the list to find all that satisfy f, then duplicate each element.
– bheklilr
Another option based on a comment by leftaroundabout:
verifyList f xs = [y | x <- xs, f x, y <- [x, x]]
My own spin on bheklilr's approach, because I feel like it:
verifyList f xs = filter f xs <**> [id, id]
The fixed point combinator doesn't always produce the right answer given the definition:
fix f = f (fix f)
The following code does not terminate:
fix (\x->x*x) 0
Of course, fix can't always produce the right answer, but I was wondering, can this be improved?
Certainly for the above example, one can implement some fix that looks like
fix f x | f x == f (f x) = f x
| otherwise = fix f (f x)
and gives the correct output.
What is the reason the above definition (or something even better, as this one only handle function with 1 parameter) is not used instead?
Fixed point combinator finds the least-defined fixed point of a function, which is ⊥ in your case (non-termination indeed is undefined value).
You can check, that in your case
(\x -> x * x) ⊥ = ⊥
i.e. ⊥ really is fixed point of \x -> x * x.
As for why is fix defined that way: the main point of fix is to allow you use anonymous recursion and for that you do not need more sophisticated definition.
Your example does not even typecheck:
Prelude> fix (\x->x*x) 0
<interactive>:1:11:
No instance for (Num (a0 -> t0))
arising from a use of `*'
Possible fix: add an instance declaration for (Num (a0 -> t0))
In the expression: x * x
In the first argument of `fix', namely `(\ x -> x * x)'
In the expression: fix (\ x -> x * x) 0
And that gives the clue as to why it doesn't work as you expect. The x in your anonymous function is supposed to be a function, not a number. The reason for this is, as Vitus suggests, that a fixpoint combinator is a way to write recursion without actually writing recursion. The general idea is that a recursive definition like
f x = if x == 0 then 1 else x * f (x-1)
can be written as
f = fix (\f' x -> if x == 0 then 1 else x * f' (x-1))
Your example
fix (\x->x*x) 0
thus corresponds to the expression
let x = x*x in x 0
which makes no sense.
I'm not entirely qualified to talk about what the "fixpoint combinator" is, or what the "least fixed point" is, but it is possible to use a fix-esque technique to approximate certain functions.
Translating Scala by Example section 4.4 to Haskell:
sqrt' :: Double -> Double
sqrt' x = sqrtIter 1.0
where sqrtIter guess | isGoodEnough guess = guess
| otherwise = sqrtIter (improve guess)
improve guess = (guess + x / guess) / 2
isGoodEnough guess = abs (guess * guess - x) < 0.001
This function works by repeatedly "improving" a guess until we determine that it is "good enough". This pattern can be abstracted:
myFix :: (a -> a) -- "improve" the guess
-> (a -> Bool) -- determine if a guess is "good enough"
-> a -- starting guess
-> a
fixApprox improve isGoodEnough startGuess = iter startGuess
where iter guess | isGoodEnough guess = guess
| otherwise = iter (improve guess)
sqrt'' :: Double -> Double
sqrt'' x = myFix improve isGoodEnough 1.0
where improve guess = (guess + x / guess) / 2
isGoodEnough guess = abs (guess * guess - x) < 0.001
See also Scala by Example section 5.3. fixApprox can be used to approximate the fixed point of the improve function passed into it. It repeatedly invokes improve on the input until the output isGoodEnough.
In fact, you can use myFix not only for approximations, but for exact answers as well.
primeAfter :: Int -> Int
primeAfter n = myFix improve isPrime (succ n)
where improve = succ
isPrime x = null [z | z <- [2..pred x], x `rem` z == 0]
This is a pretty dumb way to generate primes, but it illustrates the point. Hm...now I wonder...does something like myFix already exist? Stop...Hoogle time!
Hoogling (a -> a) -> (a -> Bool) -> a -> a, the very first hit is until.
until p f yields the result of applying f until p holds.
Well there you have it. As it turns out, myFix = flip until.
You probably meant iterate:
*Main> take 8 $ iterate (^2) (0.0 ::Float)
[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]
*Main> take 8 $ iterate (^2) (0.001 ::Float)
[1.0e-3,1.0000001e-6,1.0000002e-12,1.0000004e-24,0.0,0.0,0.0,0.0]
*Main> take 8 $ iterate (^2) (0.999 ::Float)
[0.999,0.99800104,0.9960061,0.9920281,0.9841198,0.96849173,0.93797624,0.8797994]
*Main> take 8 $ iterate (^2) (1.0 ::Float)
[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0]
*Main> take 8 $ iterate (^2) (1.001 ::Float)
[1.001,1.002001,1.0040061,1.0080284,1.0161213,1.0325024,1.0660613,1.1364866]
Here you have all the execution history explicitly available for your analysis. You can attempt to detect the fixed point with
fixed f from = snd . head
. until ((< 1e-16).abs.uncurry (-).head) tail
$ _S zip tail history
where history = iterate f from
_S f g x = f x (g x)
and then
*Main> fixed (^2) (0.999 :: Float)
0.0
but trying fixed (^2) (1.001 :: Float) will loop indefinitely, so you'd need to develop separate testing for convergence, and even then detection of repellent fixed points like 1.0 will need more elaborate investigation.
You can't define fix the way you've mentioned since f x may not even be comparable. For instance, consider the example below:
myFix f x | f x == f (f x) = f x
| otherwise = myFix f (f x)
addG f a b =
if a == 0 then
b
else
f (a - 1) (b + 1)
add = fix addG -- Works as expected.
-- addM = myFix addG (Compile error)