Consider the following code in F#
let rec ordered xs =
match xs with
| [] | [_] -> true
| x1 :: x2 :: xs' -> x1 <= x2 && ordered (x2 :: xs')
and then
let rec insert x xs =
match xs with
| [] -> [x]
| y :: ys -> if x <= y then x :: y :: ys
else y :: insert x ys
and finally
let insertKeepsOrder (x : int) xs = ordered xs ==> ordered (insert x xs)
What i can not understand is the ==> meanning in the last line!!!
What is it?
The ==> operator is part of FsCheck. It is used to express a property that should hold only if some condition is true.
So in your example:
let insertKeepsOrder (x : int) xs = ordered xs ==> ordered (insert x xs)
This means ordered (insert x xs) should be true only if ordered xs is true.
You can read more about this in the "Conditional Properties" section of the FsCheck documentation.
Related
Hi Im very new to F# as well as programming. Im trying to learn it now and have enrolled to a course but i still dont seem to get it. pls help. Im trying to rewrite the following code:
let rec msort xs =
let sz = List.length xs
if sz < 2 then xs
else let n = sz / 2
let ys = xs. [0..n-1]
let zs = xs.[n..sz-1]
in merge (msort ys) (msort zs)
//************ Utility-funktion merge
let rec merge xs ys = if List.isEmpty xs then ys else if
List.isEmpty ys then xs else let x = List.head xs
let y = List.head ys
let xs = List.tail xs
let ys = List.tail ys
in if x < y then x :: merge xs (y::ys)
else y :: merge (x::xs) ys </i>
My solution - which isnt working:
let rec msort xs =
let sz = List.length xs
match sz with
| sz < 2 -> xs
|_ -> n = sz/2
let ys = xs. [0..n-1]
let zs = xs.[n..sz-1]
in merge (msort ys) (msort zs)
//************ Utility-funktinen merge
let rec merge xs ys = match xs with |[] -> [ys]
match ys with
|[] -> [xs] |_ ->
let x = List.head xs
let y = List.head ys
let xs = List.tail xs
let ys = List.tail ys if x < y then x :: merge xs (y::ys)
|_ ->
y :: merge (x::xs) y
Notice that you can match over two values by writing them in a tuple and instead of let-binding list head and tail you can use pattern matching on the 'shape' of the list directly in the guards although the fact that the same name it's used for the whole list and later for the tail is a bit unfortunate as it can lead to confusion, but it works fine because F# shadows the values:
let rec merge xs ys =
match (xs, ys) with
| [], _ -> ys
| _, [] -> xs
| x::xs, y::ys ->
if x < y then x :: merge xs (y::ys)
else y :: merge (x::xs) ys
let rec msort xs =
let sz = List.length xs
match sz with
| sz when sz < 2 -> xs
|_ ->
let n = sz/2
let ys = xs. [0..n-1]
let zs = xs.[n..sz-1]
merge (msort ys) (msort zs)
You were missing the keyword when in the conditions of the guards.
I also fixed some minor details in your original code.
I'm implementing the merge subroutine of merge sort. I'm getting this error message when compiling: parse error on input |
merge :: [Int] -> [Int] -> [Int]
merge xs ys = go xs ys []
where go xs ys zs =
|null ys = zs ++ xs
|null xs = zs ++ ys
|(head xs) <= head ys = go (tail xs) ys (head xs : zs)
|otherwise = go xs (tail ys) (head ys : zs)
can anyone tell me why? Also is there a more succinct way of doing this? Thanks.
You can fix the syntactic error by removing the = after go xs ys zs - when defining something with guards, the = comes only after each guard, as you already have.
Apart from that, your code would be a lot cleaner if you used pattern-matching more. Instead of checking whether a list with null and then inspecting the head and tail, you can use the patterns [] to identify empty lists and (x:xs) to both identify non-empty lists and to bind the head and tail to the names x and xs, etc:
merge :: [Int] -> [Int] -> [Int]
merge xs ys = go xs ys []
where go xs [] zs = zs ++ xs
go [] ys zs = zs ++ ys
go (x:xs) (y:ys) zs
| x <= y = go xs (y:ys) (x:zs)
| otherwise = go (x:xs) ys (y:zs)
This is a reference question to this: StackOverflow in continuation monad
with whom I played a little and would need a few clarifications.
1) I suppose this:
member this.Delay(mk) = fun c -> mk () c
makes the behavior in computational workflow do the diffrence as showed by toyvo between these:
cBind (map xs) (fun xs -> cReturn (f x :: xs))
cBind (fun c -> map xs c) (fun xs -> cReturn (f x :: xs))
So I don't exactly understand what is the trick, when
(fun c -> map xs c) is only different notation of (map xs)
2) Inference issue. - In OP's second map example I found out it doesn't compile due to inference problem with v value, because it infers f as a -> b list, instead of desired a -> b. Why it infers in this way? In case let v = f x it would infer well.
3) It seems to me that VS shows inaccurate type signatures in the tooltips:
return type of the monad's Return is: ('e->'f)->f, while the return type of the Bind is only 'c->'b. -It seems it simplify ('e->'f) to only c in the Bind case, or am I missing something here?
Thanks for the clarification,
tomas
Edit - testing dump:
let cReturn x = fun k -> k x
let cBind m f =
printfn "cBind %A" <| m id
fun c -> m (fun a -> f a c)
let map_fixed f xs =
let rec map xs =
printfn "map %A" xs
match xs with
| [] -> cReturn []
| x :: xs -> cBind (fun c -> map xs c) (fun xs -> cReturn (f x :: xs))
map xs (fun x -> x)
let map f xs =
let rec map xs =
printfn "map %A" xs
match xs with
| [] -> cReturn []
| x :: xs -> cBind (map xs) (fun xs -> cReturn (f x :: xs))
map xs (fun x -> x)
[1..2] |> map_fixed ((+) 1) |> printfn "%A"
[1..2] |> map ((+) 1) |> printfn "%A"
map_fixed:
map [1; 2]
map [2]
map []
cBind []
map []
cBind [3]
map [2]
map []
cBind []
map []
[2; 3]
map:
map [1; 2]
map [2]
map []
cBind []
cBind [3]
[2; 3]
Edit to question 2:
let map f xs =
let rec map xs =
cont {
match xs with
| [] -> return []
| x :: xs ->
let v = f x // Inference ok
//let! v = cont { return f x } // ! Inference issue - question 2
let! xs = map xs
return v :: xs
}
map xs id
The issue is exactly that fun c -> map xs c is not the same as map xs. They have the same "meaning" in some sense, but their runtime semantics are different. In the latter case, evaluating the expression results in an immediate call to the map function with xs as an argument (returning another function as the result). On the other hand, evaluating fun c -> map xs c does not result in an immediate call to map! The call to map is delayed until the resulting function is actually applied. This is the critical difference that prevents a stack overflow.
Regarding your other questions, I can't quite make out what you're asking in your second question. For your third question, the compiler has inferred the most general type possible for Bind. You're right that the traditional type that you might expect is more specific than this, but it's not really a problem that you can call Bind in a wider set of contexts than is strictly necessary. And if you really want a more specific type, you can always add annotations to constrain the signature.
Using the following continuation monad:
type ContinuationMonad() =
member this.Bind (m, f) = fun c -> m (fun a -> f a c)
member this.Return x = fun k -> k x
let cont = ContinuationMonad()
I fail to see why the following gives me a stack overflow:
let map f xs =
let rec map xs =
cont {
match xs with
| [] -> return []
| x :: xs ->
let! xs = map xs
return f x :: xs
}
map xs id;;
let q = [1..100000] |> map ((+) 1)
While the following doesn't:
let map f xs =
let rec map xs =
cont {
match xs with
| [] -> return []
| x :: xs ->
let! v = fun g -> g(f x)
let! xs = map xs
return v :: xs
}
map xs id;;
let q = [1..100000] |> map ((+) 1)
To fix your example, add this method to your definition of the monad:
member this.Delay(mk) = fun c -> mk () c
Apparently the part that overflows is the destruction of the large input list in the recursive call of map. Delaying it solves the problem.
Note that your second version puts the recursive call to map behind another let! which desugars to Bind and an extra lambda, in effect delaying the recursive call to map.
I had to pursue a few false trails before reaching this conclusion. What helped was observing that StackOverflow is thrown by OCaml as well (albeit at a higher N) unless the recursive call is delayed. While F# TCO has some quirks, OCaml is more proven, so this convinced me that the problem is indeed with the code and not the compiler:
let cReturn x = fun k -> k x
let cBind m f = fun c -> m (fun a -> f a c)
let map f xs =
(* inner map loop overflows trying to pattern-match long lists *)
let rec map xs =
match xs with
| [] -> cReturn []
| x :: xs ->
cBind (map xs) (fun xs -> cReturn (f x :: xs)) in
map xs (fun x -> x)
let map_fixed f xs =
(* works without overflowing by delaying the recursive call *)
let rec map xs =
match xs with
| [] -> cReturn []
| x :: xs ->
cBind (fun c -> map xs c) (fun xs -> cReturn (f x :: xs)) in
map xs (fun x -> x)
let map_fused f xs =
(* manually fused version avoids the problem by tail-calling `map` *)
let rec map xs k =
match xs with
| [] -> k []
| x :: xs ->
map xs (fun xs -> k (f x :: xs)) in
map xs (fun x -> x)
The F# compiler is sometimes not very clever - in the first case it computes map xs then f x and then joins them, so map xs is not in a tail position. In the second case, it can reorder the map xs to be in tail position easily.
I have a simple f# quick sort function defined as:
let rec qsort(xs:List<int>) =
let smaller = xs |> List.filter(fun e -> e < xs.Head)
let larger = xs |> List.filter(fun e -> e > xs.Head)
match xs with
| [] -> []
| _ -> qsort(smaller)#[xs.Head]#qsort(larger)
Is there a way in f# to write it more like Haskell:
qsort :: [Int] -> [Int]
qsort [] = []
qsort (x:xs) =
qsort smaller ++ [x] ++ qsort larger
where
smaller = [a | a <- xs, a <= x]
larger = [b | b <- xs, b >= x]
I know the f# algorithm is missing a <= and >=. The question is more about syntax/readibility.
Thanks.
This is the most 'Haskellian' way I can think of, the only thing missing is being able to declare smaller/larger as a 'where' clause:
let rec qsort:int list -> int list = function
| [] -> []
| x::xs -> let smaller = [for a in xs do if a<=x then yield a]
let larger = [for b in xs do if b>x then yield b]
qsort smaller # [x] # qsort larger
I know it's not part of your question, but I'd use List.partition to split the list in smaller/larger in a single pass:
let rec qsort = function
| [] -> []
| x::xs -> let smaller,larger = List.partition (fun y -> y<=x) xs
qsort smaller # [x] # qsort larger
You want your second match clause to be x :: xs, and to use the # (append) operator where your Haskell example uses ++:
let rec qsort xs =
match xs with
| [] -> []
| x :: xs ->
let smaller = qsort (xs |> List.filter(fun e -> e <= x))
let larger = qsort (xs |> List.filter(fun e -> e > x))
smaller # [x] # larger
It's not quite the same as the Haskell definition by cases syntax, but hopefully similar enough for you!
...Or you could make a tail recursive qsort by using CPS:
let qSort lst =
let rec qs l cont =
match l with
| [] -> cont []
| (x::xs) -> qs (List.filter (fun e -> e <= x) xs) (fun smaller ->
qs (List.filter (fun e -> e > x) xs) (fun larger ->
smaller # (x :: larger) |> cont))
qs lst id
This seems to be as concise as it can get (combining the ideas from other answers, and using currying for operators):
let rec qsort = function
| [] -> []
| (x:int) :: xs ->
let smaller = List.filter ((>=) x) xs
let larger = List.filter ((<) x) xs
qsort smaller # [x] # qsort larger
haskell 'where' syntax, which lets you use the name of a function before its definition, kind of maps to f# 'let rec ... and'
let qsort xs =
let rec sort xs =
match ls with
|[] -> ....
|h::t -> (smaller t) # h # (larger t)
and smaller ls = //the 'and' lets you define the
// function after where it is used,
// like with 'where' in haskell
... define smaller in terms of sort
and larger ls =
... same
sort xs
let rec QuickSort l =
match l with
| [] -> []
| _ -> QuickSort([for e in l do if e < (List.head l) then yield e]) #[(List.head l)]# QuickSort([for e in l do if e > (List.head l) then yield e])
Don't forget that List has a partition method, so
let rec quicksort ls =
match ls with
| [] -> []
| h :: t -> let fore, aft = List.partition (fun i -> i < h) t
(quicksort fore) # (h :: quicksort aft)
I had done some analysis of sorting algorithms in F# a few years ago in a very imperative style; I was trying to beat the .NET stock implementation, and managed to do so here. Went to make the following reply to myself today, but FPish won't let me create an account. Argh! Gotta make my post somewhere, and here's as good as anywhere, lol...
While reading "Learn You a Haskell For Great Good" yesterday, the author set up an example for implementing quicksort. The description was quite clear and even before I got to the sample code, an elegant recursive solution (in Haskell) popped into my head. Guess I had never really had an intuitive feel for how quicksort does its thing, because the trivial solution is quite easy, if not very efficient.
Here is my version in F#:
let rec quicksort = function
| [] -> []
| pivot :: xs ->
(left pivot xs) # pivot :: (right pivot xs)
and left pivot xs = quicksort [ for x in xs do if x <= pivot then yield x ]
and right pivot xs = quicksort [ for x in xs do if x > pivot then yield x ]
And, the equivalent Haskell (I like this one... clean!):
quicksort :: Ord a => [a] -> [a]
quicksort [] = []
quicksort (pivot : xs) =
left ++ pivot : right
where
left = quicksort [ x | x <- xs, x <= pivot ]
right = quicksort [ x | x <- xs, x > pivot ]
For grins, here's another F# version (mostly tail-recursive) that's about 2x the speed of the trivial version. Haven't bothered to time this against my original post, though, so no idea how it stacks up to the mutable version in my OP on FPish.net (FSHub) from a few years ago...
let rec quicksort' xs =
let rec aux pivot left right = function
| [] -> (quicksort' left) # pivot :: (quicksort' right)
| x :: xs ->
if x <= pivot then
aux pivot (x :: left) right xs
else
aux pivot left (x::right) xs
match xs with
| [] -> []
| x :: xs -> aux x [] [] xs