Point-free: confused about where to put parenthesis - syntax

let list_to_string = (String.concat "") (List.map (String.make 1));;
This is wrong, but how do I make it understand that the argument is still to be supplied? The argument is expected to be of type char list, I.e. the first function that needs to be applied to it is the (List.map (String.make 1)), and then pass it to String.concat "". I think I've tried all combinations of parenthesis I could think of... no joy so far.
Help?
I also figured I could do it like this:
let ($) f g x = f (g x);;
let list_to_string = (String.concat "") $ (List.map (String.make 1));;
But just wanted to make sure there isn't a better way.

The real (and always perplexing) problem is that OCaml doesn't have a built-in function composition operator. So it's not so good out of the box for pointfree coding. If you really want to get fancy with it, you also need flip, which inverts the order of the arguments of a two-argument function.
let flip f a b = f b a
At any rate, I don't see any problem with your solution once you've defined function composition as $. You can leave out some of the parentheses:
# let lts = String.concat "" $ List.map (String.make 1);;
val lts : char list -> string = <fun>
As to efficiency, I assume this is more of a puzzle than a practical bit of code. Otherwise you should use the functions that Edwin suggests.

I don't think that partial application helps here, just write out the function parameter:
let list_to_string x = String.concat "" (List.map (String.make 1) x)
This isn't very efficient though, it would be better to create just one string and fill it with characters.
If you use Batteries then see Batstring.of_list, and if you use Core then see String.of_char_list

You can definitely just define a function composition operator in OCaml. It just can't be dot because that's already an operator in OCaml.
(* I just made up this symbol *)
let (^.^) f g x = f (g x)
let list_to_string = String.concat "" ^.^ List.map (String.make 1);;

Related

Functional programming with OCAML

I'm new to functional programming and I'm trying to implement a basic algorithm using OCAML for course that I'm following currently.
I'm trying to implement the following algorithm :
Entries :
- E : a non-empty set of integers
- s : an integer
- d : a positive float different of 0
Output :
- T : a set of integers included into E
m <- min(E)
T <- {m}
FOR EACH e ∈ sort_ascending(E \ {m}) DO
IF e > (1+d)m AND e <= s THEN
T <- T U {e}
m <- e
RETURN T
let f = fun (l: int list) (s: int) (d: float) ->
List.fold_left (fun acc x -> if ... then (list_union acc [x]) else acc)
[(list_min l)] (list_sort_ascending l) ;;
So far, this is what I have, but I don't know how to handle the modification of the "m" variable mentioned in the algorithm... So I need help to understand what is the best way to implement the algorithm, maybe I'm not gone in the right direction.
Thanks by advance to anyone who will take time to help me !
The basic trick of functional programming is that although you can't modify the values of any variables, you can call a function with different arguments. In the initial stages of switching away from imperative ways of thinking, you can imagine making every variable you want to modify into the parameters of your function. To modify the variables, you call the function recursively with the desired new values.
This technique will work for "modifying" the variable m. Think of m as a function parameter instead.
You are already using this technique with acc. Each call inside the fold gets the old value of acc and returns the new value, which is then passed to the function again. You might imagine having both acc and m as parameters of this inner function.
Assuming list_min is defined you should think the problem methodically. Let's say you represent a set with a list. Your function takes this set and some arguments and returns a subset of the original set, given the elements meet certain conditions.
Now, when I read this for the first time, List.filter automatically came to my mind.
List.filter : ('a -> bool) -> 'a list -> 'a list
But you wanted to modify the m so this wouldn't be useful. It's important to know when you can use library functions and when you really need to create your own functions from scratch. You could clearly use filter while handling m as a reference but it wouldn't be the functional way.
First let's focus on your predicate:
fun s d m e -> (float e) > (1. +. d)*.(float m) && (e <= s)
Note that +. and *. are the plus and product functions for floats, and float is a function that casts an int to float.
Let's say the function predicate is that predicate I just mentioned.
Now, this is also a matter of opinion. In my experience I wouldn't use fold_left just because it's just complicated and not necessary.
So let's begin with my idea of the code:
let m = list_min l;;
So this is the initial m
Then I will define an auxiliary function that reads the m as an argument, with l as your original set, and s, d and m the variables you used in your original imperative code.
let rec f' l s d m =
match l with
| [] -> []
| x :: xs -> if (predicate s d m x) then begin
x :: (f' xs s d x)
end
else
f' xs s d m in
f' l s d m
Then for each element of your set, you check if it satisfies the predicate, and if it does, you call the function again but you replace the value of m with x.
Finally you could just call f' from a function f:
let f (l: int list) (s: int) (d: float) =
let m = list_min l in
f' l s d m
Be careful when creating a function like your list_min, what would happen if the list was empty? Normally you would use the Option type to handle those cases but you assumed you're dealing with a non-empty set so that's great.
When doing functional programming it's important to think functional. Pattern matching is super recommended, while pointers/references should be minimal. I hope this is useful. Contact me if you any other doubt or recommendation.

Some OCAML concerns

So I have a couple of questions, as a newbie trying to learn O'Caml.
In functions, I often times see a | what does that mean? Also, why are functions some times defined as:
let rec a = function
Why does it specifically equal to function and then the code?
My main question however is, I was trying to write a function that would count the number of times an element exists in a list, so if I had 1, 5,5,6,9 with the target val as 5, then I'd return 2, if target val was 9, then I'd return 1, since it repeats once.
here is my attempt, please tell me what I'm doing wrong:
let rec track (x, l)= let rec helper(x,l, count)
in counthelper
match l with [] --> count
| (a::as) -> if(x = a)
then helper(as,l, count+1)
else count( as, l, count);;
The match and function keywords take a list of patterns to be matched. The | symbol is used to separate the different patterns. That's why it shows up so frequently in OCaml code.
The function keyword is like an abbreviation for fun and match. It lets you define a function as a set of patterns to be matched against an argument.
Your code has let rec helper (x, l, count) in .... This isn't a proper let expression. You want something like this: let helper (x, l, count) = def in expr.
More generally your code might look like this:
let track (x, l) =
let rec helper (x, l, count) =
... definition of helper ...
in
helper (x, l, 0)
As a side comment, you're using tuples for function parameters. It's more idiomatic in OCaml to use currying, i.e., to have separate parameters more like this:
let track x l =
...
This lets you do partial application (specify only some of the parameters), and also is cleaner syntactically.
Update
Your latest code doesn't return a value because it has infinite recursion.
Usually | means pattern matching.
let rec means that function can be recursive (call itself). Tutorial.
This is my solution where some useful symbols are changed to _ symbols. Let it be an exercise for you:
let rec count y xs =
let rec inner n = function
| __ -> n
| ______________ -> inner (n+1) xs
| ____ -> inner n xs
in
inner 0 xs;;
Your implementation has some issues.
The most obvious one is that you are using as in pattern matching. You can't us keyword in pattern matching this way.
You need to reread chapter about function declarations. It seems that you are mixing it with function invocation.
You are using not curried functions. You did some in C before, don't you?
You are using if when using using when is nicer. This construction is called guard.

adding a number to a list within a function OCaml

Here is what I have and the error that I am getting sadly is
Error: This function has type 'a * 'a list -> 'a list
It is applied to too many arguments; maybe you forgot a `;'.
Why is that the case? I plan on passing two lists to the deleteDuplicates function, a sorted list, and an empty list, and expect the duplicates to be removed in the list r, which will be returned once the original list reaches [] condition.
will be back with updated code
let myfunc_caml_way arg0 arg1 = ...
rather than
let myfunc_java_way(arg0, arg1) = ...
Then you can call your function in this way:
myfunc_caml_way "10" 123
rather than
myfunc_java_way("10, 123)
I don't know how useful this might be, but here is some code that does what you want, written in a fairly standard OCaml style. Spend some time making sure you understand how and why it works. Maybe you should start with something simpler (eg how would you sum the elements of a list of integers ?). Actually, you should probably start with an OCaml tutorial, reading carefully and making sure you aunderstand the code examples.
let deleteDuplicates u =
(*
u : the sorted list
v : the result so far
last : the last element we read from u
*)
let rec aux u v last =
match u with
[] -> v
| x::xs when x = last -> aux xs v last
| x::xs -> aux u (x::v) x
in
(* the first element is a special case *)
match u with
[] -> []
| x::xs -> List.rev (aux xs [x] x)
This is not a direct answer to your question.
The standard way of defining an "n-ary" function is
let myfunc_caml_way arg0 arg1 = ...
rather than
let myfunc_java_way(arg0, arg1) = ...
Then you can call your function in this way:
myfunc_caml_way "10" 123
rather than
myfunc_java_way("10, 123)
See examples here:
https://github.com/ocaml/ocaml/blob/trunk/stdlib/complex.ml
By switching from myfunc_java_way to myfunc_caml_way, you will be benefited from what's called "Currying"
What is 'Currying'?
However please note that you sometimes need to enclose the whole invocation by parenthesis
myfunc_caml_way (otherfunc_caml_way "foo" "bar") 123
in order to tell the compiler not to interpret your code as
((myfunc_caml_way otherfunc_caml_way "foo") "bar" 123)
You seem to be thinking that OCaml uses tuples (a, b) to indicate arguments of function calls. This isn't the case. Whenever some expressions stand next to each other, that's a function call. The first expression is the function, and the rest of the expressions are the arguments to the function.
So, these two lines:
append(first,r)
deleteDuplicates(remaining, r)
Represent a function call with three arguments. The function is append. The first argument is (first ,r). The second argument is deleteDuplicates. The third argument is (remaining, r).
Since append has just one argument (a tuple), you're passing it too many arguments. This is what the compiler is telling you.
You also seem to be thinking that append(first, r) will change the value of r. This is not the case. Variables in OCaml are immutable. You can't do anything that will change the value of r.
Update
I think you have too many questions for SO to help you effectively at this point. You might try reading some OCaml tutorials. It will be much faster than asking a question here for every error you see :-)
Nonetheless, here's what "match failure" means. It means that somewhere you have a match that you're applying to an expression, but none of the patterns of the match matches the expression. Your deleteDuplicates code clearly has a pattern coverage error; i.e., it has a pattern that doesn't cover all cases. Your first match only works for empty lists or for lists of 2 or more elements. It doesn't work for lists of 1 element.

Is there an F# equivalent of Enumerable.DefaultIfEmpty?

After searching quite a bit, I couldn't find an F# equivalent of Enumerable.DefaultIfEmpty.
Does something similar exists in F# (perhaps in a different, idiomatic, way)?
To preserve the laziness of the sequence, we could work with the enumerator's state.
let DefaultIfEmpty (l:'t seq) (d:'t) =
seq{
use en = l.GetEnumerator()
if en.MoveNext() then
yield en.Current
while en.MoveNext() do
yield en.Current
else
yield d }
Seq module functions operate and return IEnumerable<_>'s and DefaultIfEmpty operate and return IEnumerable<_>'s. How about just wrap it in function that is composable.
let inline DefaultIfEmpty d l = System.Linq.Enumerable.DefaultIfEmpty(l, d)
This also preserves laziness.
example:
Seq.empty |> DefaultIfEmpty 0
Update
I've made an open source library inlining many extension and static methods, including Enumerable.defaultIfEmpty -- ComposableExtesions
There are a few options:
Use DefaultIfEmpty which might be non-idiomatic but will work
write your own like so:
let DefaultIfEmpty (l:'t seq) (d:'t) =
match Seq.length l with |0 -> seq [d] |_ -> l
Worry about infinite sequences
let DefaultIfEmpty (l:'t seq) (d:'t) =
match Seq.isEmpty l with |true -> seq [d] |false -> l

Repa 3 performance and correct usage of 'now'

There is a basic monad question in here, unrelated to Repa, plus several Repa-specific questions.
I am working on a library using Repa3. I am having trouble getting efficient parallel code. If I make my functions return delayed arrays, I get excruciatingly slow code that scales very well up to 8 cores. This code takes over 20GB of memory per the GHC profiler, and runs several orders of magnitude slower than the basic Haskell unboxed vectors.
Alternatively, if I make all of my functions return Unboxed manifest arrays (still attempting to use fusion within the functions, for example when I do a 'map'), I get MUCH faster code (still slower than using Haskell unboxed vectors) that doesn't scale at all, and in fact tends to get slightly slower with more cores.
Based on the FFT example code in Repa-Algorithms, it seems the correct approach is to always return manifest arrays. Is there ever a case where I should be returning delayed arrays?
The FFT code also makes plentiful use of the 'now' function. However, I get a type error when I try to use it in my code:
type Arr t r = Array t DIM1 r
data CycRingRepa m r = CRTBasis (Arr U r)
| PowBasis (Arr U r)
fromArray :: forall m r t. (BaseRing m r, Unbox r, Repr t r) => Arr t r -> CycRingRepa m r
fromArray =
let mval = reflectNum (Proxy::Proxy m)
in \x ->
let sh:.n = extent x
in assert (mval == 2*n) PowBasis $ now $ computeUnboxedP $ bitrev x
The code compiles fine without the 'now'. With the 'now', I get the following error:
Couldn't match type r' withArray U (Z :. Int) r'
`r' is a rigid type variable bound by
the type signature for
fromArray :: (BaseRing m r, Unbox r, Repr t r) =>
Arr t r -> CycRingRepa m r
at C:\Users\crockeea\Documents\Code\LatticeLib\CycRingRepa.hs:50:1
Expected type: CycRingRepa m r
Actual type: CycRingRepa m (Array U DIM1 r)
I don't think this is my problem. It would be helpful if someone could explain the how the Monad works in 'now'. By my best estimation, the monad seems to be creating a 'Arr U (Arr U r)'. I'm expecting a 'Arr U r', which would then match the data constructor pattern. What is going on and how do I fix this?
The type signatures are:
computeUnboxedP :: Fill r1 U sh e => Array r1 sh e -> Array U sh e
now :: (Shape sh, Repr r e, Monad m) => Array r sh e -> m (Array r sh e)
It would be helpful to have a better idea of when it is appropriate to use 'now'.
A couple other Repa questions:
Should I explicitly call computeUnboxedP (as in the FFT example code), or should I use the more general computeP (because the unbox part is inferred by my data type)?
Should I store delayed or manifest arrays in the data type CycRingRepa?
Eventually I would also like this code to work with Haskell Integers. Will this require me to write new code that uses something other than U arrays, or could I write polymorphic code that creates U arrays for unbox types and some other array for Integers/boxed types?
I realize there are a lot of questions in here, and I appreciate any/all answers!
Here's the source code for now:
now arr = do
arr `deepSeqArray` return ()
return arr
So it's really just a monadic version of deepSeqArray. You can use either of these to force evaluation, rather than hanging on to a thunk. This "evalulation" is different than the "computation" forced when computeP is called.
In your code, now doesn't apply, since you're not in a monad. But in this context deepSeqArray wouldn't help either. Consider this situation:
x :: Array U Int Double
x = ...
y :: Array U Int Double
y = computeUnboxedP $ map f x
Since y refers to x, we'd like to be sure x is computed before starting to compute y. If not, the available work won't be distributed correctly among the gang of threads. To get this to work out, it's better to write y as
y = deepSeqArray x . computeUnboxedP $ map f x
Now, for a delayed array, we have
deepSeqArray (ADelayed sh f) y = sh `deepSeq` f `seq` y
Rather than computing all the elements, this just makes sure the shape is computed, and reduces f to weak-head normal form.
As for manifest vs delayed arrays, there are certainly time delayed arrays are preferable.
multiplyMM arr brr
= [arr, brr] `deepSeqArrays`
A.sumP (A.zipWith (*) arrRepl brrRepl)
where trr = computeUnboxedP $ transpose2D brr
arrRepl = trr `deepSeqArray` A.extend (Z :. All :. colsB :. All) arr
brrRepl = trr `deepSeqArray` A.extend (Z :. rowsA :. All :. All) trr
(Z :. _ :. rowsA) = extent arr
(Z :. colsB :. _ ) = extent brr
Here "extend" generates a new array by copying the values across some set of new dimensions. In particular, this means that
arrRepl ! (Z :. i :. j :. k) == arrRepl ! (Z :. i :. j' :. k)
Thankfully, extend produces a delayed array, since it would be a waste to go through the trouble of all this copying.
Delayed arrays also allow the possiblity of fusion, which is impossible if the array is manifest.
Finally, computeUnboxedP is just computeP with a specialized type. Giving computeUnboxedP explicitly might allow GHC to optimize better, and makes the code a little clearer.
Repa 3.1 no longer requires the explict use of now. The parallel computation functions are all monadic, and automatically apply deepSeqArray to their results. The repa-examples package also contains a new implementation of matrix multiply that demonstrates their use.

Resources