Apply functions to each tuple in a list - f#

Excuse me if this is quite basic, I'm new to functional programming and F#.
I have to create a function that takes a list of tuples (string*int) and return a list of tuples (string *int)
So basically I want to apply some functions to each tuple in pairList and return a list of tuples.
I am guessing I could do this through a recursive function.
I have the following code so far:
let rec aFunction (pairList:List<string*int>): List<string*int> =
match pairList with
| [] -> []
| head :: tail -> [fst head,snd (someFunc1 (someFunc2 (fst head,snd head)))]
This basically just apply the various functions to only the head of the list and return me a list of tuple.
In order to get it working for the whole list I tried the following:
| head :: tail -> [fst head,snd (someFunc1 (someFunc2 (fst head,snd head)));aFunction tail]
But I get the following error :
This expression was expected to have type string * int but here has type List < string * int >

This function does in fact exist already - it is called List.map.
To analyse your error, when you do [a;b] a and b need to have the same type.
What you wanted was to use the concatenation operator :: like this:
| head :: tail -> (fst head,snd (someFunc1 (someFunc2 (fst head,snd head)))) :: (aFunction tail)
but you can actually make this neater by pattern matching in a better way
| (a,b) :: tail -> (a,snd (someFunc1 (someFunc2 (a,b)))) :: (aFunction tail)

John Palmers answer is more than good enough, but I would probably also go all the way and do about the following for clarity and readability:
let someFunc1 = id //just to make it compile
let someFunc2 = id //just to make it compile
let someFunc3 = someFunc2 >> someFunc1 >> snd
let someFunc4 head = fst head, someFunc3 head
let rec aFunction (pairList:List<string*int>): List<string*int> =
match pairList with
| [] -> []
| head :: tail -> someFunc4 head :: (aFunction tail)

And here's the List.map option John alluded to:
// make a helper function that converts a single tuple
let convertTuple (s, i) =
let i1 = (s, i) |> someFunc2 |> someFunc1 |> snd // pipeline operator helps remove parens
s, i1
// now you can simply
let aFunction pairList = List.map convertTuple pairList
// or even more simply using pointfree syntax:
let aFunction = List.map convertTuple
Note the above aFunction is so simple you may not even want a special function for it: it's perhaps more intuitive just to type out List.map convertTuple myList in full everywhere you need it.
That's the general idea with F#; start with some helpers that are the minimal transforms you want to make, and then build them up into bigger things using the combinators.

Related

Taking two streams and combining them in OCaml

I want to take two streams of integers in increasing order and combine them into one stream that contains no duplicates and should be in increasing order. I have defined the functionality for streams in the following manner:
type 'a susp = Susp of (unit -> 'a)
let force (Susp f) = f()
type 'a str = {hd : 'a ; tl : ('a str) susp }
let merge s1 s2 = (* must implement *)
The first function suspends computation by wrapping a computation within a function, and the second function evaluates the function and provides me with the result of the computation.
I want to emulate the logic of how you go about combining lists, i.e. match on both lists and check which elements are greater, lesser, or equal and then append (cons) the integers such that the resulting list is sorted.
However, I know I cannot just do this with streams of course as I cannot traverse it like a list, so I think I would need to go integer by integer, compare, and then suspend the computation and keep doing this to build the resulting stream.
I am at a bit of a loss how to implement such logic however, assuming it is how I should be going about this, so if somebody could point me in the right direction that would be great.
Thank you!
If the the input sequences are sorted, there is not much difference between merging lists and sequences. Consider the following merge function on lists:
let rec merge s t =
match s, t with
| x :: s , [] | [], x :: s -> x :: s
| [], [] -> s
| x :: s', y :: t' ->
if x < y then
x :: (merge s' t)
else if x = y then
x :: (merge s' t')
else
y :: (merge s t')
This function is only using two properties of lists:
the ability to split the potential first element from the rest of the list
the ability to add an element to the front of the list
This suggests that we could rewrite this function as a functor over the signature
module type seq = sig
type 'a t
(* if the seq is non-empty we split the seq into head and tail *)
val next: 'a t -> ('a * 'a t) option
(* add back to the front *)
val cons: 'a -> 'a t -> 'a t
end
Then if we replace the pattern matching on the list with a call to next, and the cons operation with a call to cons, the previous function is transformed into:
module Merge(Any_seq: seq ) = struct
open Any_seq
let rec merge s t =
match next s, next t with
| Some(x,s), None | None, Some (x,s) ->
cons x s
| None, None -> s
| Some (x,s'), Some (y,t') ->
if x < y then
cons x (merge s' t)
else if x = y then
cons x (merge s' t')
else
cons y (merge s t')
end
Then, with list, our implementation was:
module List_core = struct
type 'a t = 'a list
let cons = List.cons
let next = function
| [] -> None
| a :: q -> Some(a,q)
end
module List_implem = Merge(List_core)
which can be tested with
let test = List_implem.merge [1;5;6] [2;4;9]
Implementing the same function for your stream type is then just a matter of writing a similar Stream_core module for stream.

Ocaml Type Error For enumerate example

Hello I am new to OCaml And I am trying to learn the basic syntax of tail recursion. I wrote the following code in order to get a list and return the list with duples containing element and its index. for example
["b";"c";"dd";] -> [("b", 0); ("c", 1); ("dd", 2)]
I wrote the following code:
let enumerateWithTail lst =
let rec inside lst acc index =
match lst with
| [] -> acc
| x::xs -> inside xs (x,index)::acc (index+1)
in inside lst [] 0;;
This doesn't work but my professors example(which at least I think its pretty similar) works. My professors code is:
let enumerate lst =
let rec aux lst acc =
match lst with
| [] -> acc
| x::xs -> let (eList, index) = acc
in aux xs ((x, index)::eList, index+1)
in List.rev(fst(aux lst ([], 0)))
Can someone please explain why my code gives the error:
This expression has type 'a * 'b
but an expression was expected of type 'c list
Thanks in advance!
The problem is with precedence. Function application has higher precedence than any operator, including ::, so this:
inside xs (x,index)::acc (index+1)
is interpreted as:
(inside xs (x,index)) :: (acc (index+1))
whereas what you want is:
inside xs ((x,index)::acc) (index+1)

Tail Recursive map f#

I want to write a tail recursive function to multiply all the values in a list by 2 in F#. I know there is a bunch of ways to do this but i want to know if this is even a viable method. This is purely for educational purposes. I realize that there is a built in function to do this for me.
let multiply m =
let rec innerfunct ax = function
| [] -> printfn "%A" m
| (car::cdr) -> (car <- car*2 innerfunct cdr);
innerfunct m;;
let mutable a = 1::3::4::[]
multiply a
I get two errors with this though i doubt they are the only problems.
This value is not mutable on my second matching condition
and
This expression is a function value, i.e. is missing arguments. Its type is 'a list -> unit. for when i call length a.
I am fairly new to F# and realize im probably not calling the function properly but i cant figure out why. This is mostly a learning experience for me so the explanation is more important than just fixing the code. The syntax is clearly off, but can i map *2 to a list just by doing the equivalent of
car = car*2 and then calling the inner function on the cdr of the list.
There are a number of issues that I can't easily explain without showing intermediate code, so I'll try to walk through a commented refactoring:
First, we'll go down the mutable path:
As F# lists are immutable and so are primitive ints, we need a way to mutate that thing inside the list:
let mutable a = [ref 1; ref 3; ref 4]
Getting rid of the superfluous ax and arranging the cases a bit, we can make use of these reference cells:
let multiply m =
let rec innerfunct = function
| [] -> printfn "%A" m
| car :: cdr ->
car := !car*2
innerfunct cdr
innerfunct m
We see, that multiply only calls its inner function, so we end up with the first solution:
let rec multiply m =
match m with
| [] -> printfn "%A" m
| car :: cdr ->
car := !car*2
multiply cdr
This is really only for it's own purpose. If you want mutability, use arrays and traditional for-loops.
Then, we go up the immutable path:
As we learnt in the mutable world, the first error is due to car not being mutable. It is just a primitive int out of an immutable list. Living in an immutable world means we can only create something new out of our input. What we want is to construct a new list, having car*2 as head and then the result of the recursive call to innerfunct. As usual, all branches of a function need to return some thing of the same type:
let multiply m =
let rec innerfunct = function
| [] ->
printfn "%A" m
[]
| car :: cdr ->
car*2 :: innerfunct cdr
innerfunct m
Knowing m is immutable, we can get rid of the printfn. If needed, we can put it outside of the function, anywhere we have access to the list. It will always print the same.
We finish by also making the reference to the list immutable and obtain a second (intermediate) solution:
let multiply m =
let rec innerfunct = function
| [] -> []
| car :: cdr -> car*2 :: innerfunct cdr
innerfunct m
let a = [1; 3; 4]
printfn "%A" a
let multiplied = multiply a
printfn "%A" multiplied
It might be nice to also multiply by different values (the function is called multiply after all and not double). Also, now that innerfunct is so small, we can make the names match the small scope (the smaller the scope, the shorter the names):
let multiply m xs =
let rec inner = function
| [] -> []
| x :: tail -> x*m :: inner tail
inner xs
Note that I put the factor first and the list last. This is similar to other List functions and allows to create pre-customized functions by using partial application:
let double = multiply 2
let doubled = double a
All that's left now is to make multiply tail-recursive:
let multiply m xs =
let rec inner acc = function
| [] -> acc
| x :: tail -> inner (x*m :: acc) tail
inner [] xs |> List.rev
So we end up having (for educational purposes) a hard-coded version of let multiply' m = List.map ((*) m)
F# is a 'single-pass' compiler, so you can expect any compilation error to have a cascading effect beneath the error. When you have a compilation error, focus on that single error. While you may have more errors in your code (you do), it may also be that subsequent errors are only consequences of the first error.
As the compiler says, car isn't mutable, so you can assign a value to it.
In Functional Programming, a map can easily be implemented as a recursive function:
// ('a -> 'b) -> 'a list -> 'b list
let rec map f = function
| [] -> []
| h::t -> f h :: map f t
This version, however, isn't tail-recursive, since it recursively calls map before it cons the head onto the tail.
You can normally refactor to a tail-recursive implementation by introducing an 'inner' implementation function that uses an accumulator for the result. Here's one way to do that:
// ('a -> 'b) -> 'a list -> 'b list
let map' f xs =
let rec mapImp f acc = function
| [] -> acc
| h::t -> mapImp f (acc # [f h]) t
mapImp f [] xs
Here, mapImp is the last operation to be invoked in the h::t case.
This implementation is a bit inefficient because it concatenates two lists (acc # [f h]) in each iteration. Depending on the size of the lists to map, it may be more efficient to cons the accumulator and then do a single reverse at the end:
// ('a -> 'b) -> 'a list -> 'b list
let map'' f xs =
let rec mapImp f acc = function
| [] -> acc
| h::t -> mapImp f (f h :: acc) t
mapImp f [] xs |> List.rev
In any case, however, the only reason to do all of this is for the exercise, because this function is already built-in.
In all cases, you can use map functions to multiply all elements in a list by two:
> let mdouble = List.map ((*) 2);;
val mdouble : (int list -> int list)
> mdouble [1..10];;
val it : int list = [2; 4; 6; 8; 10; 12; 14; 16; 18; 20]
Normally, though, I wouldn't even care to define such function explicitly. Instead, you use it inline:
> List.map ((*) 2) [1..10];;
val it : int list = [2; 4; 6; 8; 10; 12; 14; 16; 18; 20]
You can use all the above map function in the same way.
Symbols that you are creating in a match statement are not mutable, so when you are matching with (car::cdr) you cannot change their values.
Standard functional way would be to produce a new list with the computed values. For that you can write something like this:
let multiplyBy2 = List.map (fun x -> x * 2)
multiplyBy2 [1;2;3;4;5]
This is not tail recursive by itself (but List.map is).
If you really want to change values of the list, you could use an array instead. Then your function will not produce any new objects, just iterate through the array:
let multiplyArrayBy2 arr =
arr
|> Array.iteri (fun index value -> arr.[index] <- value * 2)
let someArray = [| 1; 2; 3; 4; 5 |]
multiplyArrayBy2 someArray

Accumulator function for tag cloud

I'm trying to write a tail-recursion function that will look at a list of distinct words, a list of all words, and return a list with the count of occurrences of each word. I'm actually reading the words out of files in a directory, but I can't seem to get the tail-recursion to compile. This is what I have so far:
let countOccurence (word:string) list =
List.filter (fun x -> x.Equals(word)) list
//(all words being a list of all words across several files)
let distinctWords = allWords |> Seq.distinct
let rec wordCloud distinct (all:string list) acc =
match distinct with
| head :: tail -> wordCloud distinct tail Array.append(acc, (countOccurence head all)) //<- What am I doing with my life?
| [] -> 0
I realize this is probably a fairly straightforward question, but I've been banging my head for an hour on this final piece of the puzzle. Any thoughts?
There are several issues with the statement as given:
Use of Array.append to manipulate lists
Typos
Incorrect use of whitespace to group things together
Try expressing the logic as a series of steps instead of putting everything into a single, unreadable line of code. Here's what I did to understand the problems with the above expression:
let rec wordCloud distinct (all:string list) acc =
match distinct with
| head :: tail ->
let count = countOccurence head all
let acc' = acc |> List.append count
wordCloud distinct tail acc'
| [] -> 0
This compiles, but I don't know if it does what you want it to do...
Notice the replacement of Array.append with List.append.
This is still tail recursive, since the call to wordCloud sits in the tail position.
After several hours more work, I came up with this:
let countOccurance (word:string) list =
let count = List.filter (fun x -> word.Equals(x)) list
(word, count.Length)
let distinctWords = allWords |> Seq.distinct |> Seq.toList
let print (tup:string*int) =
match tup with
| (a,b) -> printfn "%A: %A" a b
let rec wordCloud distinct (all:string list) (acc:(string*int) list) =
match distinct with
| [] -> acc
| head :: tail ->
let accumSoFar = acc # [(countOccurance head all)]
wordCloud tail all accumSoFar
let acc = []
let cloud = (wordCloud distinctWords allWords acc)
let rec printTup (tupList:(string*int) list) =
match tupList with
| [] -> 0
| head :: tail ->
printfn "%A" head
printTup tail
printTup cloud
This problem actually has a pretty straightforward solution, if you take a step back and simply type in what you want to do.
/// When you want to make a tag cloud...
let makeTagCloud (words: string list) =
// ...take a list of all words...
words
// ...then walk along the list...
|> List.fold (fun cloud word ->
// ...and check if you've seen that word...
match cloud |> Map.tryFind word with
// ...if you have, bump the count...
| Some count -> cloud |> Map.add word (count+1)
// ...if not, add it to the map...
| None -> cloud |> Map.add word 1) Map.empty
// ...and change the map back into a list when you are done.
|> Map.toList
Reads like poetry ;)

F# idiomatic way of transforming text

Myello! So I am looking for a concise, efficient an idiomatic way in F# to parse a file or a string. I have a strong preference to treat the input as a sequence of char (char seq). The idea is that every function is responsible to parse a piece of the input, return the converted text tupled with the unused input and be called by a higher level function that chains the unused input to the following functions and use the results to build a compound type. Every parsing function should therefore have a signature similar to this one: char seq -> char seq * 'a . If, for example, the function's responsibility is simply to extract the first word, then, one approach would be the following:
let parseFirstWord (text: char seq) =
let rec forTailRecursion t acc =
let c = Seq.head t
if c = '\n' then
(t, acc)
else
forTailRecursion (Seq.skip 1 t) (c::acc)
let rest, reversedWord = forTailRecursion text []
(rest, List.reverse reversedWord)
Now, of course the main problem with this approach is that it extracts the word in reverse order and so you have to reverse it. Its main advantages however are that is uses strictly functional features and proper tail recursion. One could avoid the reversing of the extracted value while losing tail recursion:
let rec parseFirstWord (text: char seq) =
let c = Seq.head t
if c = '\n' then
(t, [])
else
let rest, tail = parseFirstWord (Seq.skip 1 t)
(rest, (c::tail))
Or use a fast mutable data structure underneath instead of using purely functional features, such as:
let parseFirstWord (text: char seq) =
let rec forTailRecursion t queue =
let c = Seq.head t
if c = '\n' then
(t, queue)
else
forTailRecursion (Seq.skip 1 t) (queue.Enqueu(c))
forTailRecursion text (new Queue<char>())
I have no idea how to use OO concepts in F# mind you so corrections to the above code are welcome.
Being new to this language, I would like to be guided in terms of the usual compromises that an F# developer makes. Among the suggested approaches and your own, which should I consider more idiomatic and why? Also, in that particular case, how would you encapsulate the return value: char seq * char seq, char seq * char list or evenchar seq * Queue<char>? Or would you even consider char seq * String following a proper conversion?
I would definitely have a look at FSLex. FSYacc, FParsec. However if you just want to tokenize a seq<char> you can use a sequence expression to generate tokens in the right order. Reusing your idea of a recursive inner function, and combinining with a sequence expression, we can stay tail recursive like shown below, and avoid non-idiomatic tools like mutable data structures.
I changed the separator char for easy debugging and the signature of the function. This version produces a seq<string> (your tokens) as result, which is probably easier to consume than a tuple with the current token and the rest of the text. If you just want the first token, you can just take the head. Note that the sequence is generated 'on demand', i.e. the input is parsed only as tokens are consumed through the sequence. Should you need the remainder of the input text next to each token, you can yield a pair in loop instead, but I'm guessing the downstream consumer most likely wouldn't (furthermore, if the input text is itself a lazy sequence, possibly linked to a stream, we don't want to expose it as it should be iterated through only in one place).
let parse (text : char seq) =
let rec loop t acc =
seq {
if Seq.isEmpty t then yield acc
else
let c, rest = Seq.head t, Seq.skip 1 t
if c = ' ' then
yield acc
yield! loop rest ""
else yield! loop rest (acc + string c)
}
loop text ""
parse "The FOX is mine"
val it : seq<string> = seq ["The"; "FOX"; "is"; "mine"]
This is not the only 'idiomatic' way of doing this in F#. Every time we need to process a sequence, we can look at the functions made available in the Seq module. The most general of these is fold which iterates through a sequence once, accumulating a state at each element by running a given function. In the example below accumulate is such a function, that progressively builds the resulting sequence of tokens. Since Seq.fold doesn't run the accumulator function on an empty sequence, we need the last two lines to extract the last token from the function's internal accumulator.
This second implementation keeps the nice characteriestics of the first, i.e. tail recursion (inside the fold implementation, if I'm not mistaken) and processing of the input sequence on demand. It also happens to be shorter, albeit a bit less readable probably.
let parse2 (text : char seq) =
let accumulate (res, acc) c =
if c = ' ' then (Seq.append res (Seq.singleton acc), "")
else (res, acc + string c)
let (acc, last) = text |> Seq.fold accumulate (Seq.empty, "")
Seq.append acc (Seq.singleton last)
parse2 "The FOX is mine"
val it : seq<string> = seq ["The"; "FOX"; "is"; "mine"]
One way of lexing/parsing in a way truly unique to F# is by using active patterns. The following simplified example shows the general idea. It can process a calculation string of arbitrary length without producing a stack overflow.
let rec (|CharOf|_|) set = function
| c :: rest when Set.contains c set -> Some(c, rest)
| ' ' :: CharOf set (c, rest) -> Some(c, rest)
| _ -> None
let rec (|CharsOf|) set = function
| CharOf set (c, CharsOf set (cs, rest)) -> c::cs, rest
| rest -> [], rest
let (|StringOf|_|) set = function
| CharsOf set (_::_ as cs, rest) -> Some(System.String(Array.ofList cs), rest)
| _ -> None
type Token =
| Int of int
| Add | Sub | Mul | Div | Mod
| Unknown
let lex: string -> _ =
let digits = set ['0'..'9']
let ops = Set.ofSeq "+-*/%"
let rec lex chars =
seq { match chars with
| StringOf digits (s, rest) -> yield Int(int s); yield! lex rest
| CharOf ops (c, rest) ->
let op =
match c with
| '+' -> Add | '-' -> Sub | '*' -> Mul | '/' -> Div | '%' -> Mod
| _ -> failwith "invalid operator char"
yield op; yield! lex rest
| [] -> ()
| _ -> yield Unknown }
List.ofSeq >> lex
lex "1234 + 514 / 500"
// seq [Int 1234; Add; Int 514; Div; Int 500]

Resources