F#中的Haskell应用函数

kog*_*oia 1 f# haskell functional-programming functor applicative

在Haskell中,我们可以编写如下代码:

// (<*>) :: Applicative f => f (a -> b) -> f a -> f b
// const :: a -> b -> a
// id :: b -> b
let id = const <*> const
Run Code Online (Sandbox Code Playgroud)

如何在F#中做同样的事情?

我尝试编写类似这样的代码,但它不一样

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
Run Code Online (Sandbox Code Playgroud)

但是在Haskell中id::b->b,在F#中id:'a->'a Option

我做错了什么?如何实现相同的结果?

PS:正如我所知道的那样,我们的值被包含在一个上下文中,就像Functors一样,函数也包含在上下文中!

Some((+)3) and Some(2)
Run Code Online (Sandbox Code Playgroud)

在这种情况下,Context是Option

Applay方法是这样的:

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 
Run Code Online (Sandbox Code Playgroud)

Dan*_*zer 10

我对你的代码试图实现的内容感到有点困惑,因为它有类型

(a -> Maybe b) -> Maybe a -> Maybe b
Run Code Online (Sandbox Code Playgroud)

这是绑定的了单子结构我们平时灌输式Maybe/ option用,但如果你想与我们在Haskell函数的应用性实例来工作,它没有任何意义.我们需要改变两件事,第一件事是我们需要使用函数应用程序,以使代码达到预期的效果.应该有这种类型

 (a -> (b -> c)) -> (a -> b) -> (a -> c)
Run Code Online (Sandbox Code Playgroud)

所以我们可以这样写

 let ( <*> ) f x a = (f a) (x a)
Run Code Online (Sandbox Code Playgroud)

现在,如果我们步骤原始的例子

 (cnst <*> cnst) a = (cnst a) (cnst a)
                   = a
Run Code Online (Sandbox Code Playgroud)

所以我们确实cnst <*> cnst = id按要求提供了.