简体   繁体   English

F#中的Haskell应用函子

[英]Haskell Applicative Functor in F#

In Haskell we can write code like this: 在Haskell中,我们可以编写如下代码:

// (<*>) :: 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#? 如何在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 但是在Haskell id::b->b ,在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! PS:据我所知,在Applicative中,我们的值包装在上下文中,就像函子和函数也包装在上下文中一样!

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

In this case Context is Option 在这种情况下,上下文是选项

And Applay method is like this: 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 

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. 这是通常为Maybe / option注入的monad结构的绑定类型,但是如果您尝试使用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. 因此我们确实具有cnst <*> cnst = id

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM