Search code examples
haskellf#functional-programmingfunctorapplicative

Haskell Applicative Functor in F#


In Haskell we can write code like this:

// (<*>) :: Applicative f => f (a -> b) -> f a -> f b
// const :: a -> b -> a
// id :: b -> b
let id = const <*> const

How to do same thing in F#?

I try write code something like this, but it isn't same

let ( <*> ) f v =
    match v with
    | Some v' -> 
        match f with 
        | Some f' -> Some (f' v')
        | _ -> None
    | _ -> None
let cnst a _ = a
let id = cnst <*> cnst // but it seems impossible
let id' x = (Some (cnst x)) <*> (Some(cnst x x)) // it works

But in Haskell id::b->b, in F# id:'a->'a Option

What I do wrong? How to achieve the same result?

PS: As I know with an Applicative, our values are wrapped in a context, just like Functors and functions are wrapped in a context too!

Some((+)3) and Some(2)

In this case Context is Option

And Applay method is like this:

let Apply funInContext valInContext =
    match funInContext with  // unwrap function
    | Some f -> 
        match valInContext with // unwrap value
        | Some v -> Some(f v) // applay function on value and wrap it
        | _ -> None
    | _ -> None 

Solution

  • I'm slightly confused by what your code is trying to achieve because it has the type

    (a -> Maybe b) -> Maybe a -> Maybe b
    

    This is the type of bind for the monad structure we usually imbue Maybe/option with but it doesn't make sense if you're trying to work with the applicative instance for functions that we have in Haskell. There are two things we need to change then, the first is that we need to work with functions and applicatives in order to have the code achieve the desired effect. That ought to have the type

     (a -> (b -> c)) -> (a -> b) -> (a -> c)
    

    So we can write this as

     let ( <*> ) f x a = (f a) (x a)
    

    Now if we step the original example

     (cnst <*> cnst) a = (cnst a) (cnst a)
                       = a
    

    so we indeed have that cnst <*> cnst = id as required.