Not sure what you are asking here. "map" and "fold" do work on the Choice type.

They are class functions, in the Seq class, so to see them with intellisense you enter Seq. (and see all the Seq functions)

eg.

// Create and transform a sequence of Choice<int,bool>

1
let s = seq ([ Choice1Of2(0); Choice2Of2(false); Choice1Of2(3) ])

val s : seq<Choice<int,bool>> = [Choice1Of2; Choice2Of2; Choice1Of2]

// Transform each Choice1 0 into Choice2 false (and leave others untouched)

1
let HitZeros s = Seq.map (fun c2 -> match c2 with | Choice1Of2(0) -> Choice2Of2(false) | _ as x -> x) s

val HitZeros : seq<Choice<int,bool>> -> seq<Choice<int,bool>>

> HitZeros s;;
val it : seq<Choice<int,bool>> = seq [Choice2Of2; Choice2Of2; Choice1Of2]

Or where you looking for something else?

By on 11/1/2009 8:04 PM ()

No I wasn't talking about a Choice Seq, but rather Choice itself:

let anwerOrError:Choice<string,Error>= Choice1Of2("answer")

let output= Choice.fold (fun s->s) (fun e -> e.message) answerOrError

let something:Choice<string,Error>= Choice.map (fun s-> s+"Yeah") answerOrError.choice1

In the same way you can have map, bind, toOption...

If I am not clear I can provide an implementation of such functions.

Thanks

Sadek

By on 11/2/2009 2:22 AM ()

You could implement these functions yourself. However note that:

  • The ChoiceMofN exist mostly as an implementation artifact of F# Active Patterns. I might consider using my own type, rather than the core library type, on which to base such a module. (There is nothing approaching what Haskell has for "Either" in any of the F# standard libraries, so you'll not be interoperating with any other code, regardless of whether you use the library choice type or not.)
  • F# has exceptions, so consider them. In some cases where I'd use "Either" in Haskell as an error monad, I might use .Net exceptions in F# instead. (In other cases, I would continue to use "Either" style return values.)
By on 11/2/2009 10:25 AM ()

module Either=

type Either<'a,'b>= Left of 'a

|Right of 'b

member x.left= LeftProjection x

member x.right=RightProjection x

and LeftProjection<'a,'b>= LeftProjection of Either<'a,'b>

member x.get= match x with

LeftProjection(Left a) -> Some a

|LeftProjection(Right _)-> None

and RightProjection<'a,'b>= RightProjection of Either<'a,'b>

member x.get= match x with

RightProjection(Left _) -> None

|RightProjection(Right b)-> Some b

let map m1 m2 e= match e with

Left a -> Left (m1 a)

|Right b -> Right (m2 b)

let fold f1 f2 e= match e with

Left a -> f1 a

|Right b -> f2 b

module LeftProjection=

let map f lp= match lp with

LeftProjection (Left a)-> LeftProjection (Left (f a))

|LeftProjection (Right _) -> lp

let bind f lp= match lp with

LeftProjection (Left a)-> match f a with

Left aa -> LeftProjection (Left aa)

|Right b -> LeftProjection (Right b)

|LeftProjection (Right b) -> LeftProjection (Right b)

let e (LeftProjection either)= either

module RightProjection=

let map f lp= match lp with

RightProjection (Right a)-> RightProjection (Left (f a))

|RightProjection (Left _) -> lp

let bind f lp= match lp with

RightProjection (Right b)-> match f b with

Left a -> RightProjection (Left a)

|Right bb -> RightProjection (Right b)

|RightProjection (Left a) -> RightProjection (Left a)

let e (LeftProjection either)= either

By on 11/2/2009 2:57 PM ()

Fair enough. Pity they are not in the Fsharp.Core, Scala, for instance, has Either type and the monad functions defined on it.

I, personally, wouldn't use .Net exceptions much since they are only runtime and I prefer to include my errors as much as possible in the type system and use higher order functions to manipulate them.

Thanks

Sadek

By on 11/2/2009 11:16 AM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper