F# - Restricting Discriminated Union case in function input - f#

Let's say I'm trying to build a simple Stack in F# as follows:
type Stack =
| Empty
| Stack of String list
(I know I can define it recursively but for this example, let's assume I'd like to have a list in there)
Then I define a push operation like this:
let push item deck =
match deck with
| Empty -> Stack [item]
| Stack d -> Stack (item::d)
But when I reach the pop operation... I'm not having success. I wanted to do something like this:
let pop (Stack d) =
match d with
| h::[] -> h,Empty
| h::t -> h,(Stack t)
For now, let's also try to ignore the fact that I might want a peek/pop pair of operations instead of returning a tuple. What I wanted to try was to write a pop operation which would only accept a Stack which is not empty in the first place.
In other words, I only wanted this function to accept one of the cases of the Discriminated Union. However, I immediately get the warning: "Incomplete pattern matches on this expression. For example, the value 'Empty' may indicate a case not covered by the pattern(s)'.
As expected (after the warning), the following code:
let empty = Empty
let s,st = pop empty
... compiles and fails at run time. I wanted it to fail at compile time.
I'm aware I could use other options for this, such as:
let pop stack =
match stack with
| Empty -> None, Empty
| Stack (h::[]) -> Some h,Empty
| Stack (h::t) -> Some h,(Stack t)
or:
let pop stack =
match stack with
| Empty -> Error "Empty Stack"
| Stack (h::[]) -> Ok (h,Empty)
| Stack (h::t) -> Ok (h,(Stack t))
(and on both of these cases I might not even need the Empty case at all...)
But I was trying to make something more restrictive. So... what am I missing here? Is there a way to achieve what I was attempting? Does it even make any sense to want that?

Think about what you're trying to achieve carefully. Consider the following function:
let foo (s: Stack) = pop s
Should foo compile or should it be rejected? Think about it.
I will assume here that you have already thought about it, and offered the only reasonable answer: the "restriction" that you seek should now apply to foo as well. That is, whoever calls foo must also supply only non-empty stack.
Ok, fair enough. But let's go all the way to the turtles:
let main argv =
printf "Provide directive: "
let s =
match Console.ReadLine() with
| "empty" -> Empty
| _ -> Stack [1; 2; 3]
let p = pop s
0
Now should this program compile or be rejected? Obviously, it depends on the user input. The type of the program depends on runtime values. This is actually an active area of research, and there is a name for it: such program is called Dependently Typed. In plain terms it's when values (may) carry types with them, but unlike .NET RTTI, the compiler has visibility into those types and can prove things about their relationships. Fascinating stuff.
F#, for better or worse, doesn't support dependent types, and probably never will.
Now, I will assume that you're ok with not having dependent types, and would like instead to have your "restriction" only for cases when it is definitely known (at compile time) that the stack is not empty.
If this is the case, then your problem is easily solvable by splitting your DU in two:
type NonEmptyStack<'a> = NonEmptyStack of top: 'a * rest: 'a list
type Stack<'a> = Empty | NonEmpty of NonEmptyStack<'a>
let push item stack =
match stack with
| Empty -> NonEmptyStack (item, [])
| NonEmpty (NonEmptyStack (top, rest)) -> NonEmptyStack (item, top::rest)
let pop (NonEmptyStack (top,rest)) =
match rest with
| i::tail -> (top, Stack (NonEmptyStack (i, tail)))
| _ -> (top, Empty)
Notice how push always returns a non-empty stack, and pop accepts only non-empty stack. The types encode the meaning. This is what they're supposed to do.

The problem lies in your model -- there are two ways to represent an empty stack:
let empty1 = Empty
let empty2 = Stack []
Given this, it's not clear how you want it to behave. This is why I would suggest either going with a recursively defined stack, or or just using a list. Here's your options:
// type alias
type Stack<'a> = 'a list
// single-case DU
type Stack<'a> = Stack of 'a list
// traditional recursive type (which happens to be exactly equivalent to list<'a>)
type Stack<'a> = Empty | Stack of 'a * Stack<'a>
That said, if you really just want to keep it the way you have it right now, and get it to compile, you just need to match the extra "empty" representation:
let pop stack =
match stack with
| Empty | Stack [] -> None, Empty
| Stack (h::[]) -> Some h,Empty
| Stack (h::t) -> Some h,(Stack t)

Related

checking if enough elements in a F# list

Right now I have a few instances like this:
let doIt someList =
if someList |> List.truncate 2 |> List.length >= 2 then
someList[0] + someList[1]
else
0
I need to grab the top 2 elements of a list quite often to see changes, but in some cases I don't have enough elements and I need to make sure there are at least 2.
The best way I've found so far is to truncate the list before getting its length, but this creates allocations for no reason.
Is there a better method?
I think I would suggest pattern matching in this case:
let doIt someList =
match someList with
| a :: b :: _ -> a + b
| _ -> 0
Here, a and b are the ints in the list, while _ represents a discarded of list int. This way you don't have to pull the first two elements out of the list with an index, as they are already available as a and b. The last case of the match catches any pattern that was not matched earlier, such as cases with zero, one or three-or-more elements.
This should be a cheap operation, as F# lists are implemented as a singly linked list. So [a;b;c;d] would be represented as a::(b::(c::(d::[]))). a and b are matched, while the rest (c::(d::[])) is left untouched (and is put in the _ slot). It does not need to create a new list to do so.

Is there a name for this pattern "type 'a foldedSequence = Empty | Value of 'a * (unit->'a foldedSequence )"

I have been working with some f# parsers and some streaming software and I find myself using this pattern more and more. I find it to be a natural alternative to sequences and it has some natural advantages.
here are some example functions using the type.
type foldedSequence<'a> =
| Empty
| Value of ' a * (unit -> 'a foldedSequence)
let rec createFoldedSequence fn state =
match fn state with
| None -> Empty
| Some(value, nextState) ->
Value(value, (fun () -> unfold fn nextState))
let rec filter predicate =
function
| Empty -> Empty
| Value(value, nextValue) ->
let next() = filter predicate(nextValue())
if predicate value then Value(value, next)
else next()
let toSeq<'t> =
Seq.unfold<'t foldedSequence, 't>(function
| Empty -> None
| Value(value, nextValue) -> Some(value, nextValue()))
It has been very helpful I would like to know if it has a name so I can research some tips and tricks for it
To add to the existing answers, I think Haskellers might call a generalised version of this this a list monad transformer. The idea is that your type definition looks almost like ordinary F# list except that there is some additional aspect to it. You can imagine writing this as:
type ListTransformer<'T> =
| Empty
| Value of 'T * M<ListTransformer<'T>>
By supplying specific M, you can define a number of things:
M<'T> = 'T gives you the ordinary F# list type
M<'T> = unit -> 'T gives you your sequence that can be evaluated lazily
M<'T> = Lazy<'T> gives you LazyList (which caches already evaluated elements)
M<'T> = Async<'T> gives you asynchronous sequences
It is also worth noting that in this definition LazyTransformer<'T> is not itself a delayed/lazy/async value. This can cause problems in some cases - e.g. when you need to perform some async operation to decide whether the stream is empty - and so a better definition is:
type ListTransformer<'T> = M<ListTransformerInner<'T>>
and ListTransformerInner<'T> =
| Empty
| Value of 'T * ListTransformer<'T>
This sounds like LazyList which used to be in the "powerpack" and I think now lives here:
http://fsprojects.github.io/FSharpx.Collections/reference/fsharpx-collections-lazylist-1.html
https://github.com/fsprojects/FSharpx.Collections/blob/master/src/FSharpx.Collections/LazyList.fs
Your type is close to how an iteratee would be defined, and since you already mention streaming, this might be the concept you're looking for.
Iteratee IO is an approach to lazy IO outlined by Oleg Kiselyov. Apart from Haskell, implementations exist for major functional languages, including F# (as part of FSharpx.Extras).
This is how FSharpx defines an Iteratee:
type Iteratee<'Chunk,'T> =
| Done of 'T * Stream<'Chunk>
| Error of exn
| Continue of (Stream<'Chunk> -> Iteratee<'Chunk,'T>)
See also this blog post: Iteratee in F# - part 1. Note that there doesn't seem to be a part 2.

Why am I forced to return a typed value for None?

Why am I forced to return a typed value for None?
let getHand = function
| Some(card1, card2) -> card1, card2
| None -> // ?
In my case, I want to deal a hand. But it doesn't make sense for me to still deal a hand if no hand exists via Options.
What am I not considering?
What pattern should I be using?
Specifically, if no hand exists, then I want to grab a full deck.
Why would a method yield a complex typed result if no result exists?
| None -> // Why am I still required to yield a typed result
All values in F# have types. Functions do as well.
The getHand function looks like it takes as input an option value. Since an option value is a Discriminated Union, the function must address both cases of possible input. The compiler and the type system helps you do that.
A part of a function's type is its return value. In F#, a function can only have a single return type (this is also true for C#). Thus, you'll need to address both the Some and the None case, and make the function return the same type in both cases. Sometimes, though, that 'same type' can be another Discriminated Union.
From the wording of your question, it sounds like you want to return some cards in both cases, so perhaps return a list of cards:
let getHand = function
| Some(card1, card2) -> [card1; card2]
| None -> []
Here, I've returned an empty list in the None case, but if you wish, you can instead populate the return value with a default list.
An alternative solution to Mark Seemann's answer is to return option as well. You could write (changed because your own function would become trivial):
let getFirstCard = function
| Some (card1, card2) -> Some card1
| None -> None
or better Option.map (fun (card1, card2) -> card1).
The final (and generally bad) solution is to throw an exception on None using Option.get.

F#: Creating a collection of integers from user input

I'm rather new to F# so the question may be fairly elementary. Still, I couldn't find any suggestion on SO.
I'm playing with an algorithmic task in F#. As a first step I want to create a collection of integers from user console input. The number of inputs is not defined. And I don't wont to use any while loops. I would prefer as much idiomatic approach as possible.
In a recursive function I'm reading the result and parsing it with Int32.TryParse. I match the bool result using match ... with. If successful then I attach a new value to a collection. Otherwise I return the collection.
Below is my code:
let rec getNumList listSoFar =
let ok, num = Int32.TryParse(Console.ReadLine())
match ok with
| false -> listSoFar
| true -> getNumList num::listSoFar
let l = getNumList []
And the error I get:
Type mismatch. Expecting a
'a
but given a
'a list
I'm aware I'm using types incorrectly, though I don't understand what exactly is wrong. Any explanation highly appreciated.
In the match branch
| true -> getNumList num::listSoFar
You should use parenthesis:
| true -> getNumList (num::listSoFar)
Because function application has higher priority than the :: operator

F#/OCaml: How to avoid duplicate pattern match?

Have a look at this F#/OCaml code:
type AllPossible =
| A of int
| B of int*int
| ...
| Z of ...
let foo x =
....
match x with
| A(value) | B(value,_) -> (* LINE 1 *)
(* do something with the first (or only, in the case of A) value *)
...
(* now do something that is different in the case of B *)
let possibleData =
match x with
| A(a) -> bar1(a)
| B(a,b) -> bar2(a+b)
| _ -> raise Exception (* the problem - read below *)
(* work with possibleData *)
...
| Z -> ...
So what is the problem?
In function foo, we pattern match against a big list of types.
Some of the types share functionality - e.g. they have common
work to do, so we use "|A | B ->" in LINE 1, above.
We read the only integer (in the case of A), or the first integer
(in the case of B) and do something with it.
Next, we want to do something that is completely different, depending
on whether we work on A or B (i.e. call bar1 or bar2).
We now have to pattern match again, and here's the problem: In this
nested pattern match, unless we add a 'catchAll' rule (i.e. '_'),
the compiler complains that we are missing cases - i.e. it doesn't
take into account that only A and B can happen here.
But if we add the catchAll rule, then we have a far worse problem:
if at some point we add more types in the list of LINE1
(i.e. in the line '|A | B ->' ... then the compiler will NOT help
us in the nested match - the '_' will catch them, and a bug will
be detected at RUNTIME. One of the most important powers of
pattern matching - i.e. detecting such errors at compile-time - is lost.
Is there a better way to write this kind of code, without having
to repeat whatever work is shared amongst A and B in two separate
rules for A and B? (or putting the A-and-B common work in a function
solely created for the purpose of "local code sharing" between A and B?)
EDIT: Note that one could argue that the F# compiler's behaviour is buggy in this case -
it should be able to detect that there's no need for matching beyond A and B
in the nested match.
If the datatype is set in stone - I would also prefer local function.
Otherwise, in OCaml you could also enjoy open (aka polymorphic) variants :
type t = [`A | `B | `C]
let f = function
| (`A | `B as x) ->
let s = match x with `A -> "a" | `B -> "b" in
print_endline s
| `C -> print_endline "ugh"
I would just put the common logic in a local function, should be both faster and more readable. Matches nested that way is pretty hard to follow, and putting the common logic in a local function allows you to ditch the extra matching in favour of something that'll get inlined anyway.
Hmm looks like you need to design the data type a bit differently such as:
type AorB =
| A of int
| B of int * int
type AllPossible =
| AB of AorB
| C of int
.... other values
let foo x =
match x with
| AB(v) ->
match v with
| A(i) -> () //Do whatever need for A
| B(i,v) -> () // Do whatever need for B
| _ -> ()
Perhaps the better solution is that rather than
type All =
|A of int
|B of int*int
you have
type All =
|AorB of int * (int Option)
If you bind the data in different ways later on you might be better off using an active pattern rather than a type, but the result would be basically the same
I don't really agree that this should be seen as a bug - although it would definitely be convenient if the case was handled by the compiler.
The C# compiler doesn't complain to the following and you wouldn't expect it to:
var b = true;
if (b)
if (!b)
Console.WriteLine("Can never be reached");

Resources