How do I do this haskell in F# cleanly?
add 1 2 x = 3 + x
add 1 x y = 1 + x + y
add z x y = z + x + y
You can't overload the function itself, but you can use pattern matching directly:
let add z x y = // curried multiple parameters
match z, x, y with // convert to three-tuple to match on
| 1, 2, x -> 3 + x
| 1, x, y -> 1 + x + y
| z, x, y -> z + x + y
Usage is as expected: add 1 2 3
If you're willing to use tuples as arguments (ie forgo currying and partial application), you can even write it more shorthand:
let add = // expect three-tuple as first (and only) parameter
function // use that one value directly to match on
| 1, 2, x -> 3 + x
| 1, x, y -> 1 + x + y
| z, x, y -> z + x + y
Usage now is: add (1, 2, 3)
Recall in Haskell that the general form of functions as a list of declarations with patterns:
f pat1 ... = e1
f pat2 ... = e2
f pat3 ... = e3
is just sugar for the case analysis:
f x1 .. xn = case (x1, .. xn) of
(pat1, ..., patn) -> e1
(pat2, ..., patn) -> e2
(pat3, ..., patn) -> e3
so the same translation can be made to other languages with pattern matching but without declaration-level patterns.
This is purely syntactic. Languages like Haskell, Standard ML and Mathematica allow you to write out different match cases as if they were different functions:
factorial 0 = 1
factorial 1 = 1
factorial n = n * factorial(n-1)
whereas languages like OCaml and F# require you to have a single function definition and use match or equivalent in its body:
let factorial = function
| 0 -> 1
| 1 -> 1
| n -> n * factorial(n-1)
Note that you don't have to copy the function name over and over again using this syntax and you can factor match cases more easily:
let factorial = function
| 0 | 1 -> 1
| n -> n * factorial(n-1)
As yamen wrote, do currying with let f a b = match a, b with ... in F#.
In the classic red-black tree implementation, I find the duplication of the function names and right-hand sides in Standard ML and Haskell quite ugly:
balance :: RB a -> a -> RB a -> RB a
balance (T R a x b) y (T R c z d) = T R (T B a x b) y (T B c z d)
balance (T R (T R a x b) y c) z d = T R (T B a x b) y (T B c z d)
balance (T R a x (T R b y c)) z d = T R (T B a x b) y (T B c z d)
balance a x (T R b y (T R c z d)) = T R (T B a x b) y (T B c z d)
balance a x (T R (T R b y c) z d) = T R (T B a x b) y (T B c z d)
balance a x b = T B a x b
compared to the equivalent OCaml or F#:
let balance = function
| B, z, (T(R, y, T(R, x, a, b), c) | T(R, x, a, T(R, y, b, c))), d
| B, x, a, (T(R, z, T(R, y, b, c), d) | T(R, y, b, T(R, z, c, d))) ->
T(R, y, T(B, x, a, b), T(B, z, c, d))
| a, b, c, d -> T(a, b, c, d)
Related
I want to realize power function for my custom data type. I mean power (^) which has following signature:
(^) :: (Num a, Integral b) => a -> b -> a
And I mean that my data type MyData should be instance of Num, so I could write
x :: MyData
...
y = x ^ b
where b is some Integral. It's very easy when we need function of one class like
(+), (-), (*) :: (Num a) => a -> a -> a
We just write
instance Num MyData where
(*) x y = someFunc x y
But I have no idea how to define it taking into account that there is also Integral b. That syntax should be like
instance (Integral b) => Num MyData b where
(^) x y = someFunc x y
But I've tried a hundred of such variations and nothing works. Hours of googling also didn't help.
You don't have to do anything to define (^) for your data type; if your type has a Num instance, you get x ^ b for free, because (^) is defined for any type with a Num instance. (It basically just calls * a lot.)
Note that (^) is not a member of Num or Integral; it's just a standalone function whose type is constrained by both classes.
From https://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Real.html#%5E
(^) :: (Num a, Integral b) => a -> b -> a
x0 ^ y0 | y0 < 0 = errorWithoutStackTrace "Negative exponent"
| y0 == 0 = 1
| otherwise = f x0 y0
where -- f : x0 ^ y0 = x ^ y
f x y | even y = f (x * x) (y `quot` 2)
| y == 1 = x
| otherwise = g (x * x) (y `quot` 2) x -- See Note [Half of y - 1]
-- g : x0 ^ y0 = (x ^ y) * z
g x y z | even y = g (x * x) (y `quot` 2) z
| y == 1 = x * z
| otherwise = g (x * x) (y `quot` 2) (x * z) -- See Note [Half of y - 1]
x0 is your MyData value; the only thing (^) ever does with x0 (by virtue of it being passed as the x argument to f or g) is to multiply it by itself, so technically (^) will work as long as you have defined (*) in your Num instance.
The following function is given:
mystery a b c xs =
foldr (\x rec a b -> rec x (b + c)) (\a b -> a + b - c) xs a b
I know what the function does roughly but I have a hard time really understanding the intermediate steps. I picked following example:
mystery 1 2 3 [1, 2, 3]
Especially the use of rec is giving me a hard time. I assume that one of the final steps looks like this:
(\a b -> 3 + (b + 3 + 3 + 3) - 3) [] 1 2
So the output is 11. Could someone describe the first few steps of the execution? What happens after:
foldr (\x rec a b -> rec x (b + 3)) (\a b -> a + b - 3) [1, 2, 3] 1 2
The key here is that the foldr operation is constructing a function, then applying it to a and b; we can clarify it by adding parentheses:
mystery a b c xs =
(foldr (\x rec a b -> rec x (b + c)) (\a b -> a + b - c) xs) a b
If the xs list is empty, you get simply the initial function \a b -> a + b - c, which is then applied to a and b.
if it is not empty, then it makes succesive transformations to that function (in each iteration, "rec" is the previous function, which is used to construct a new one).
To illustrate, let's run the foldr by hand for mystery 1 2 3 [1, 2, 3];
initially, we have:
foldr (\x rec a b -> rec x (b + 3)) (\a b -> a + b - 3) [1,2,3]
Applying the equations for foldr:
foldr f z [] = z
foldr f z (x:xs) = f x (foldr f z xs)
Reduces the expression to:
(\rec a b -> rec 1 (b + 3)) (foldr (\x rec a b -> rec x (b + 3)) (\a b -> a + b - 3) [2,3])
Repeating for the next value in the list we get:
(\rec a b -> rec 1 (b + 3)) (\rec a b -> rec 2 (b + 3)) (foldr (\x rec a b -> rec x (b + 3)) (\a b -> a + b - 3) [3])
Then, for the last one:
(\rec a b -> rec 1 (b + 3)) (\rec a b -> rec 2 (b + 3)) (\rec a b -> rec 3 (b + 3)) (\a b -> a + b - 3)
We need to compose those functions, to create the final function - replacing "rec" with the previous function:
(\rec a b -> rec 1 (b + 3)) (\rec a b -> rec 2 (b + 3)) (\rec a b -> rec 3 (b + 3)) (\a b -> a + b - 3)
=> (\rec a b -> rec 1 (b + 3)) (\rec a b -> rec 2 (b + 3)) (\a b -> (\a b -> a + b - 3) 3 (b + 3))
=> (\rec a b -> rec 1 (b + 3)) (\rec a b -> rec 2 (b + 3)) (\a b -> 3 + (b + 3) - 3))
=> (\rec a b -> rec 1 (b + 3)) (\a b -> (\a b -> 3 + (b + 3) - 3)) 2 (b + 3))
=> (\rec a b -> rec 1 (b + 3)) (\a b -> 3 + ((b + 3) + 3) - 3))
=> \a b -> (\a b -> 3 + ((b + 3) + 3) - 3)) 1 (b + 3)
=> \a b -> 3 + (((b + 3) + 3) + 3) - 3)
=> \a b -> b + 9
then, we apply \a b -> b + 9 to the original "a" and "b" (which are 1 and 2), and get 2 + 9 = 11
Substituting the definition for foldr, the function reveals itself to be
mystery a b c xs =
= foldr (\x rec a b -> rec x (b + c)) (\a b -> a + b - c) xs a b
= let { g x r a b = r x (b + c); z a b = a + b - c } in
foldr g z xs a b
=> foldr g z [] a b = z a b = a + b - c
=> foldr g z [x1,x2,...,xn] a b
= g x1 (foldr g z [x2,...,xn]) a b -- g x r a b = r x (b+c)
= foldr g z [x2,...,xn] x1 (b+c)
= foldr g z [x3,...,xn] x2 (b+c*2)
= foldr g z [ ] xn (b+c*n) = xn + b + c*n - c
= last (a:xs) + b + c * (length xs - 1)
Naming the two lambda functions, using short names, makes it much easier to handle the expressions visually.
When the folding function given to foldr takes more than two parameters, it's often really a foldl in disguise. Let's see if that's true here.
mystery a b c xs = foldr (\x rec a b -> rec x (b + c)) (\a b -> a + b - c) xs a b
Uncurry the two "extra" arguments to the folding function:
mystery a b c xs = foldr (\x rec (a,b) -> rec (x,b + c)) (\(a,b) -> a + b - c) xs (a,b)
Extract function f out of the folding function, and finalStep from the nil case:
mystery a b c xs = foldr (\x rec z -> rec (f z x)) finalStep xs (a,b)
where
f (a,b) x = (x,b + c)
finalStep (a,b) = a + b - c
Replace foldr with explicit recursion:
mystery a b c xs = go xs (a,b)
where
go [] = finalStep
go (x:xs) = \z -> go xs (f z x)
f (a,b) x = (x,b + c)
finalStep (a,b) = a + b - c
Move the call to finalStep outside of go:
mystery a b c xs = finalStep $ go xs (a,b)
where
go [] = id
go (x:xs) = \z -> go xs (f z x)
f (a,b) x = (x,b + c)
finalStep (a,b) = a + b - c
Eta-expand go and reverse the order of the arguments:
mystery a b c xs = finalStep $ go (a,b) xs
where
go z [] = z
go z (x:xs) = go (f z x) xs
f (a,b) x = (x,b + c)
finalStep (a,b) = a + b - c
Now, go is exactly the definition of foldl f, so replace it with that:
mystery a b c xs = finalStep $ foldl f (a,b) xs
where
f (a,b) x = (x,b + c)
finalStep (a,b) = a + b - c
Now we have a very simple fold operation that can be trivially worked through. The key takeaway from the above is the fact that foldr (\x rec -> rec . f x) finalStep xs z and finalStep $ foldl (flip f) z xs are the same, for any f, z, and xs.
I want define kind of R data as rational numbers, where R is (denominator,numerator) and I defined as:
data R = R {n::Int,
d::Int} deriving Show
Now I tried to do a function that given two arguments(a list of R and a R) and returns a list with the equivalents of R. I try this, but give me a error of types.
equivalentes' :: [R] -> R -> [R]
equivalentes' [] _ = []
equivalentes' (x:xs) r
| (n x `mod` n r == 0) && (d x `mod` d r == 0) = (R(d n)x): equivalentes' xs r
| otherwise = equivalentes' xs r
My idea is to return something like this:
> equivalentes'[R(2,4),R(3,5),R(4,8)] (R(1,2))
[R (2,4),R (4,8)]
The problem is with the expression
R (d n) x : equivalentes' xs r
And specifically with
d n
The n function has type R -> Int, as does the d function, but you've passed n to d as its argument. Maybe you meant something like
R (d x) x
But since x has type R, this also wouldn't work, so you could have meant
R (d x) (n x)
or something similar.
On a different note, you can't do R (1, 2), because (1, 2) is a tuple of two Ints, not just two separate Ints. you could do instead R 1 2, or uncurry R (1, 2) if you really wanted to use tuples.
In Haskell, both functions and constructors are applied by juxtaposition. For example f x is the function f applied to the argument x. f x y is the function f applied to x, with the result applied to y. You can think of f x y as f applied to two arguments, x and y. You don't need parenthesis for function or constructor application, for example f (x y) means something different - in this case x is being applied to y, and f (x, y) means the function f applied to the tuple (x, y).
For your code, you need to use
R 2 4 instead of R(2,4)
R (n x) (d x) instead of R(d n)x
When we make these syntax changes, equivalentes would be written as
equivalentes :: [R] -> R -> [R]
equivalentes [] _ = []
equivalentes (x:xs) r
| (n x `mod` n r == 0) && (d x `mod` d r == 0) = R (n x) (d x): equivalentes xs r
| otherwise = equivalentes xs r
And your example would be written as
equivalentes [R 2 4,R 3 5,R 4 8] (R 1 2)
Lets say I have the following:
f (a, b) = if a == 0 then (0, 0) else (a * b, a / b)
x1 = make_strict (0, undefined)
x2 = (0, undefined)
g f :: (b -> b) -> a -> a
How do define make_strict and g:
g f x = ... f x ...
make_strict x = ...
So that:
g f x1 == undef
g f x2 == (0, 0)
Basically I want to make a strict version of a pair that I can then pass to a function which takes a pair, possibly through a wrapper g if necessary. The particular implementation of f here is just an example, the solution shouldn't rely on it. The point is I can't change f, I can only change g.
How about
makeStrict (a, b) = seq a (seq b (a, b))
I'm designing a self balancing tree in Haskell. As an exercise and because it is nice to have in your back hand.
Previously in C and Python I preferred Treaps and Splay Trees due to their simple balancing rules. I always disliked R/B Trees, since they seemed like more work than they were worth.
Now, due to the functional nature of Haskell, things seem to have changed. I can write a R/B insert function in 10 lines of code. Treaps on the other hand requires wrapping to store the random number generator, and Splay Trees are a pain to do top-down.
So I'm asking if you have experience with other types of trees?
Which ones are better at utilizing the pattern matching and top-down nature of functional languages?
Ok, I guess there wasn't a lot of references or research for answering this question. Instead I've taken the time to try your different ideas and trees. I didn't find anything a lot better than RB trees, but perhaps that's just search bias.
The RB tree can be (insertion) balanced with four simple rules, as shown by Chris Okasaki:
balance T (T R (T R a x b) y c) z d = T R (T B a x b) y (T B c z d)
balance T (T R a x (T R b y c)) z d = T R (T B a x b) y (T B c z d)
balance T a x (T R b y (T R c z d)) = T R (T B a x b) y (T B c z d)
balance T a x (T R (T R b y c) z d) = T R (T B a x b) y (T B c z d)
balance T a x b = T B a x b
AVL trees can be balanced in a similar pattern matching way. However the rules don't compress as well:
balance T (T (T a x b dx) y c (-1)) z d (-2) = T (T a x b dx) y (T c z d 0) 0
balance T a x (T b y (T c z d dz) 1 ) 2 = T (T a x b 0) y (T c z d dz) 0
balance T (T a x (T b y c 1 ) 1 ) z d (-2) = T (T a x b -1) y (T c z d 0) 0
balance T (T a x (T b y c (-1)) 1 ) z d (-2) = T (T a x b 0) y (T c z d 1) 0
balance T (T a x (T b y c _ ) 1 ) z d (-2) = T (T a x b 0) y (T c z d 0) 0
balance T a x (T (T b y c 1 ) z d (-1)) 2 = T (T a x b -1) y (T c z d 0) 0
balance T a x (T (T b y c (-1)) z d (-1)) 2 = T (T a x b 0) y (T c z d 1) 0
balance T a x (T (T b y c _ ) z d (-1)) 2 = T (T a x b 0) y (T c z d 0) 0
balance t = t
As AVL trees seams to generally be considered inferior to RB trees, they are probably not worth the extra hassle.
AA trees could theoretically be balanced nice and easily by:
balance T n (T n a x b) y c = T n a x (T n b y c) -- skew
balance T n a x (T n b y (T n c z d)) = T (n+1) (T n a x b) y (T n c z d) --split
balance T n a x b = T n a x b
But unfortunately Haskell don't like the overloading of n. It is possible that a less standard implementation of AA trees, not using ranks, but something more similar to R and B, would work well.
Splay trees are difficult because you need to focus on a single node, rather than the static structure of the tree. It can be done by merging insert and splay.
Treaps are also uneasy to do in a functional environment, as you don't have a global random generator, but need to keep instances in every node. This can be tackled by leaving the task of generating priorities to the client, but even then, you can't do priority comparison using pattern matching.
As you say Red Black trees aren't that hard to use. Have you given finger trees a look? You might be interested in augmenting your base data structure with something like a zipper. Another tree you might find interesting is the AA tree it is a simplification of Red Black Trees.
It's the one that's already implemented.
There are fine implementations in Haskell of balanced trees such as Data.Map and Data.Set. Don't they fulfill your needs? Don't reimplement, reuse.
The OCaml standard library uses an AVL tree for its map functor. It seems as though it's easier to implement than an RB-tree if you include a remove operation.