What is the best way to do "replace-if"? - haskell

I'm thinking of a function that can replace the value x with z when x is y, and do nothing otherwise, that is:
\x -> if x == y then z else x
It's only used once in my program and it's in the middle of a function chain so I don't want to define it as a named function and I think the lambda expression looks unnecessarily verbose. Instead, I'm trying to compose it from other functions. However, so far I have only come up with this cryptic (and cring-y) one:
(ap . flip . bool id $ const z) (== y)
Are there better point-free forms for such a simple function?

I don't know of anything very readable. Shortest I can get is
bool z <*> (/= y)
Further silly ways:
execState (gets (==y) >>= flip when (put z))
fromMaybe <*> flip lookup [(y, z)]

I don't approve of this very much, but a quick Hayoo search led me to the (?|) operator in the data-easy package. This package is full of such functions (with a bunch of disclaimers about "non-idiomatic haskell"). Looks like you could have
\x -> if x == y then z else x -- the cluttered Haskell form
\x -> x ?| (/= y) $ z -- the "Pythonic" form
(?| (/= y)) z -- Haskell-sections-galore of the "Pythonic" form
Jokes aside, there is also the much more reasonable fromBoolC that you will probably like:
fromBoolC z (/= y)

From lens:
import Control.Lens
f = (^. non z) . (non y # ) -- for some z and y
The if then else version is definitely better though.

You can use the Python trick of replacing a case statement with a lookup.
import Data.Map
\x -> findWithDefault x x (singleton y z)
which according to pointfree.io can be reduced to
flip (join findWithDefault) (singleton y z)
It's not exactly clear, but at the same time it separates the functional parts from the arguments. flip (join findWithDefault) does what you want, and singleton y z is a DSL-like way of specifying the exception. Stick a idExcept = flip (join findWithDefault) and exception = singleton earlier in your code, and your chain is almost readable.
my . awesome . (idExcept (exception y z)) . function . chain $ val

Related

Applying functions to lists with substitution

I was trying to make a function that quickly calculates fractions. In my particular case there a factorials, so it s kinda easy. I wrote a make_coprime function which makes two numbers coprime (and returns a pair, which bothers me a little: it sounds a bit too complicated, is there no way to make it return 2 numbers? Looks like there isn't, but just to be sure)
Now it is something like frac{numbers]/{numbers} and I want to make all of the upper ones coprime with all the lower ones.
So I have two lists and I want to apply my function to all possible pairs with substitution after that. This is where I failed. I couldn't even do it with one element and a list, my best was
f a [] = (a, [1])
f a x:xs = ((fst (make_coprime a x)), ((snd (make_coprime a x)):(snd (f (fst (make_coprime a x)) xs))))
(there is a parse error somewhere here, but I can't find it at all)
But I feel like I overcomplicate things. It sounds way simplier than it looks when I write it. Is there an elegant way to do this?
The parsing error is that you've not used parens around x:xs.
Before saying any more: Haskell functions should always come with a type signature, which makes it hugely easier to reason what we're talking about and where any. I'm not sure what you want, but likely
makeCoprime :: Integer -> Integer -> (Integer,Integer)
and
f :: Integer -> [Integer] -> (Integer, [Integer])
Apart from that (and to find other parse errors, which occur before the type system ever takes action), I'd first try to write it as readable as possible. First align everything meaningfully:
f a (x:xs) = ( (fst (make_coprime a x))
, ( (snd (make_coprime a x))
: (snd (f (fst (make_coprime a x)) xs))
)
)
ok, now there are a couple of parens that are not necessary and should be omitted: the , always seperates everything, so you never need to write e.g. (1, (2)): just make it (1,2). And function application binds more tightly than any infix operator, so you also never need to write (f x) : y, just do f x : y. That makes your code
f a (x:xs) = ( fst (make_coprime a x)
, snd (make_coprime a x)
: snd (f (fst (make_coprime a x)) xs)
)
which is already a good deal easier to understand. You could get rid of more parens by using the $ and . operators, but I'll leave that.
What I would definitely not leave, as chepner suggests, are these multiple invokations of make_coprime a x. This kind of duplication is not only code-noise, it can also make your program run very slow.
f a (x:xs) = ( fst axCoprimes
, snd axCoprimes
: snd (f (fst axCoprimes) xs)
)
where axCoprimes = make_coprime a x
Now, all you ever do with axCoprimes is eval the fst and snd components separately. Thus instead of giving the tuple one name, you should immediately match the components:
f a (x:xs) = (p₀, p₁ : snd (f p₀ xs))
where (p₀,p₁) = make_coprime a x
and there you go, that looks very clear IMO.
You only need to call coprime a x once; you can assign its return value to a name using a let statement:
f a (x:xs) = let pair = make_coprime a x
in ((fst pair), ((snd pair):(snd (f (fst pair) xs))))
(Your parse error is likely due to the missing parentheses around x:xs.)
You can simplify it more by unpacking the pair immediately instead of calling fst and snd repeatedly.
f a (x:xs) = let (n1,n2) = make_coprime a x
in (n1, (n2:(snd (f n1 xs))))

Partial application of functions and currying, how to make a better code instead of a lot of maps?

I am a beginner at Haskell and I am trying to grasp it.
I am having the following problem:
I have a function that gets 5 parameters, lets say
f x y w z a = x - y - w - z - a
And I would like to apply it while only changing the variable x from 1 to 10 whereas y, w, z and a will always be the same. The implementation I achieved was the following but I think there must be a better way.
Let's say I would like to use:
x from 1 to 10
y = 1
w = 2
z = 3
a = 4
Accordingly to this I managed to apply the function as following:
map ($ 4) $ map ($ 3) $ map ($ 2) $ map ($ 1) (map f [1..10])
I think there must be a better way to apply a lot of missing parameters to partially applied functions without having to use too many maps.
All the suggestions so far are good. Here's another, which might seem a bit weird at first, but turns out to be quite handy in lots of other situations.
Some type-forming operators, like [], which is the operator which maps a type of elements, e.g. Int to the type of lists of those elements, [Int], have the property of being Applicative. For lists, that means there is some way, denoted by the operator, <*>, pronounced "apply", to turn lists of functions and lists of arguments into lists of results.
(<*>) :: [s -> t] -> [s] -> [t] -- one instance of the general type of <*>
rather than your ordinary application, given by a blank space, or a $
($) :: (s -> t) -> s -> t
The upshot is that we can do ordinary functional programming with lists of things instead of things: we sometimes call it "programming in the list idiom". The only other ingredient is that, to cope with the situation when some of our components are individual things, we need an extra gadget
pure :: x -> [x] -- again, one instance of the general scheme
which wraps a thing up as a list, to be compatible with <*>. That is pure moves an ordinary value into the applicative idiom.
For lists, pure just makes a singleton list and <*> produces the result of every pairwise application of one of the functions to one of the arguments. In particular
pure f <*> [1..10] :: [Int -> Int -> Int -> Int -> Int]
is a list of functions (just like map f [1..10]) which can be used with <*> again. The rest of your arguments for f are not listy, so you need to pure them.
pure f <*> [1..10] <*> pure 1 <*> pure 2 <*> pure 3 <*> pure 4
For lists, this gives
[f] <*> [1..10] <*> [1] <*> [2] <*> [3] <*> [4]
i.e. the list of ways to make an application from the f, one of the [1..10], the 1, the 2, the 3 and the 4.
The opening pure f <*> s is so common, it's abbreviated f <$> s, so
f <$> [1..10] <*> [1] <*> [2] <*> [3] <*> [4]
is what would typically be written. If you can filter out the <$>, pure and <*> noise, it kind of looks like the application you had in mind. The extra punctuation is only necessary because Haskell can't tell the difference between a listy computation of a bunch of functions or arguments and a non-listy computation of what's intended as a single value but happens to be a list. At least, however, the components are in the order you started with, so you see more easily what's going on.
Esoterica. (1) in my (not very) private dialect of Haskell, the above would be
(|f [1..10] (|1|) (|2|) (|3|) (|4|)|)
where each idiom bracket, (|f a1 a2 ... an|) represents the application of a pure function to zero or more arguments which live in the idiom. It's just a way to write
pure f <*> a1 <*> a2 ... <*> an
Idris has idiom brackets, but Haskell hasn't added them. Yet.
(2) In languages with algebraic effects, the idiom of nondeterministic computation is not the same thing (to the typechecker) as the data type of lists, although you can easily convert between the two. The program becomes
f (range 1 10) 2 3 4
where range nondeterministically chooses a value between the given lower and upper bounds. So, nondetermism is treated as a local side-effect, not a data structure, enabling operations for failure and choice. You can wrap nondeterministic computations in a handler which give meanings to those operations, and one such handler might generate the list of all solutions. That's to say, the extra notation to explain what's going on is pushed to the boundary, rather than peppered through the entire interior, like those <*> and pure.
Managing the boundaries of things rather than their interiors is one of the few good ideas our species has managed to have. But at least we can have it over and over again. It's why we farm instead of hunting. It's why we prefer static type checking to dynamic tag checking. And so on...
Others have shown ways you can do it, but I think it's useful to show how to transform your version into something a little nicer. You wrote
map ($ 4) $ map ($ 3) $ map ($ 2) $ map ($ 1) (map f [1..10])
map obeys two fundamental laws:
map id = id. That is, if you map the identity function over any list, you'll get back the same list.
For any f and g, map f . map g = map (f . g). That is, mapping over a list with one function and then another one is the same as mapping over it with the composition of those two functions.
The second map law is the one we want to apply here.
map ($ 4) $ map ($ 3) $ map ($ 2) $ map ($ 1) (map f [1..10])
=
map ($ 4) . map ($ 3) . map ($ 2) . map ($ 1) . map f $ [1..10]
=
map (($ 4) . ($ 3) . ($ 2) . ($ 1) . f) [1..10]
What does ($ a) . ($ b) do? \x -> ($ a) $ ($ b) x = \x -> ($ a) $ x b = \x -> x b a. What about ($ a) . ($ b) . ($ c)? That's (\x -> x b a) . ($ c) = \y -> (\x -> x b a) $ ($ c) y = \y -> y c b a. The pattern now should be clear: ($ a) . ($ b) ... ($ y) = \z -> z y x ... c b a. So ultimately, we get
map ((\z -> z 1 2 3 4) . f) [1..10]
=
map (\w -> (\z -> z 1 2 3 4) (f w)) [1..10]
=
map (\w -> f w 1 2 3 4) [1..10]
=
map (\x -> ($ 4) $ ($ 3) $ ($ 2) $ ($ 1) $ f x) [1..10]
In addition to what the other answers say, it might be a good idea to reorder the parameters of your function, especially x is usually the parameter that you vary over like that:
f y w z a x = x - y - w - z - a
If you make it so that the x parameter comes last, you can just write
map (f 1 2 3 4) [1..10]
This won't work in all circumstances of course, but it is good to see what parameters are more likely to vary over a series of calls and put them towards the end of the argument list and parameters that tend to stay the same towards the start. When you do this, currying and partial application will usually help you out more than they would otherwise.
Assuming you don't mind variables you simply define a new function that takes x and calls f. If you don't have a function definition there (you can generally use let or where) you can use a lambda instead.
f' x = f x 1 2 3 4
Or with a lambda
\x -> f x 1 2 3 4
Currying won't do you any good here, because the argument you want to vary (enumerate) isn't the last one. Instead, try something like this.
map (\x -> f x 1 2 3 4) [1..10]
The general solution in this situation is a lambda:
\x -> f x 1 2 3 4
however, if you're seeing yourself doing this very often, with the same argument, it would make sense to move that argument to be the last argument instead:
\x -> f 1 2 3 4 x
in which case currying applies perfectly well and you can just replace the above expression with
f 1 2 3 4
so in turn you could write:
map (f 1 2 3 4) [1..10]

How come I can write the first version but not the second?

We are trying to learn Haskell (for about the 5th time!) and still struggling with some basic issues.
So how come I can write
main = print (map (* 2) [1..5])
but I can't write
myfunc x =
map ( (+ x) [1..5])
main = print (myfunc 2)
Any guidance would be appreciated --- we have the usual books but they're not really helping.
You got the parentheses wrong. You want:
myfunc x = map (+x) [1..5]
In hopes of clearing up whatever misunderstanding prompted this: In Haskell, function application is left-associative, higher "precedence" than any infix operator, and does not require any parentheses. Parentheses are used only for grouping subexpressions: (f x) y is the same as just f x y, while f (g x) needs the parentheses.

Confusion about function composition in Haskell

Consider following function definition in ghci.
let myF = sin . cos . sum
where, . stands for composition of two function (right associative). This I can call
myF [3.14, 3.14]
and it gives me desired result. Apparently, it passes list [3.14, 3.14] to function 'sum' and its 'result' is passed to cos and so on and on. However, if I do this in interpreter
let myF y = sin . cos . sum y
or
let myF y = sin . cos (sum y)
then I run into troubles. Modifying this into following gives me desired result.
let myF y = sin . cos $ sum y
or
let myF y = sin . cos . sum $ y
The type of (.) suggests that there should not be a problem with following form since 'sum y' is also a function (isn't it? After-all everything is a function in Haskell?)
let myF y = sin . cos . sum y -- this should work?
What is more interesting that I can make it work with two (or many) arguments (think of passing list [3.14, 3.14] as two arguments x and y), I have to write the following
let (myF x) y = (sin . cos . (+ x)) y
myF 3.14 3.14 -- it works!
let myF = sin . cos . (+)
myF 3.14 3.14 -- -- Doesn't work!
There is some discussion on HaskellWiki regarding this form which they call 'PointFree' form http://www.haskell.org/haskellwiki/Pointfree . By reading this article, I am suspecting that this form is different from composition of two lambda expressions. I am getting confused when I try to draw a line separating both of these styles.
Let's look at the types. For sin and cos we have:
cos, sin :: Floating a => a -> a
For sum:
sum :: Num a => [a] -> a
Now, sum y turns that into a
sum y :: Num a => a
which is a value, not a function (you could name it a function with no arguments but this is very tricky and you also need to name () -> a functions - there was a discussion somewhere about this but I cannot find the link now - Conal spoke about it).
Anyway, trying cos . sum y won't work because . expects both sides to have types a -> b and b -> c (signature is (b -> c) -> (a -> b) -> (a -> c)) and sum y cannot be written in this style. That's why you need to include parentheses or $.
As for point-free style, the simples translation recipe is this:
take you function and move the last argument of function to the end of the expression separated by a function application. For example, in case of mysum x y = x + y we have y at the end but we cannot remove it right now. Instead, rewriting as mysum x y = (x +) y it works.
remove said argument. In our case mysum x = (x +)
repeat until you have no more arguments. Here mysum = (+)
(I chose a simple example, for more convoluted cases you'll have to use flip and others)
No, sum y is not a function. It's a number, just like sum [1, 2, 3] is. It therefore makes complete sense that you cannot use the function composition operator (.) with it.
Not everything in Haskell are functions.
The obligatory cryptic answer is this: (space) binds more tightly than .
Most whitespace in Haskell can be thought of as a very high-fixity $ (the "apply" function). w x . y z is basically the same as (w $ x) . (y $ z)
When you are first learning about $ and . you should also make sure you learn about (space) as well, and make sure you understand how the language semantics implicitly parenthesize things in ways that may not (at first blush) appear intuitive.

Partial Application of Infix Functions in F#

In haskell it is posible to partially apply an infix function using sections, for instance given the infix function < (less than) one can partially apply any of the function's arguments: (5 <) , (< 5)
In other words, in haskell we have the following shorthand notation:
op :: a -> b -> c
(`op` y) === \x -> x `op` y
(x `op`) === \y -> x `op` y
Does F# have a similar concept?
No, neither of those (apart from standard partial application like (=) x).
Whereas I like the succinctness of Seq.find ((=) x), things like Seq.filter ((<) 3) (or even Seq.map (flip (-) 1)) are simply awkward to read and should immediately be replaced by a lambda expression, imo.
If you want to invent your own standards...
let lsection x f y -> f x y
let rsection f y x -> f x y
Then lsection 5 (<) === (5 <) and rsection (<) 5 === (< 5).
Though really, without language support, just put a lambda in there and it'll be clearer.

Resources