这个F#运算符的典型定义/含义是什么< *>

时间:2016-03-05 04:01:15

标签: f# operators functor applicative

相对较新的函数式编程,我仍然不熟悉所有标准运算符。事实上,他们的定义在许多语言中都是任意的,并且这些定义在附近的源代码中是不可用的,如果有的话,会使读取功能代码变得不必要地具有挑战性。

目前,我不知道WebSharper.UI.Next文档中出现的<*>

如果有一个地方列出了各种函数语言的各种运算符的所有传统定义,那将是一件好事。

2 个答案:

答案 0 :(得分:7)

我同意你的观点,最好有一个地方列出F#中使用的所有隐含约定。

<*>运算符来自Haskell,它是Applicative Functors的运算符,它的一般签名是:Applicative'<('A -> 'B)> -> Applicative'<'A> -> Applicative'<'B>这是.NET中的非法签名{{3不支持。

无论如何,没有什么能阻止你为特定的Applicative Functor定义运算符,这里是选项类型的典型定义:

let (<*>) f x =
    match (f, x) with 
    | Some f, Some x -> Some (f x) 
    | _              -> None

此处类型推断为:

val ( <*> ) : f:('a -> 'b) option -> x:'a option -> 'b option

相当于:

val ( <*> ) : f: option<('a -> 'b)> -> x: option<'a> -> option<'b>

直观的解释是它在上下文中接受一个函数,并在上下文中接受该函数的参数,然后在上下文中执行函数。

在我们的选项类型示例中,它可用于将函数应用于可能返回None值的操作的结果值:

let tryParse x = 
    match System.Int32.TryParse "100" with
    | (true, x) -> Some x
    | _ -> None

Some ((+) 10) <*> tryParse "100"

你可以利用currying并写下:

Some (+) <*> tryParse "100" <*> Some 10

代表如下:

(+) (System.Int32.Parse "100") 10

但是没有抛出异常,这就是为什么也会说Applicatives用于模拟副作用,特别是在像Haskell这样的纯函数语言中。这是higher kinds期权申请人。

但是对于不同的类型,它有不同的用途,对于列表,它可以用来压缩它们,如another sample所示。

在F#中没有定义,因为.NET类型系统无法以通用方式定义它,但是可以使用重载和静态成员约束,如post中所述,否则你将必须通过打开特定模块手动选择不同的实例,这是FsControl中使用的方法。

答案 1 :(得分:1)

刚刚在其他主题的文档中发现......

    let ( <*> ) f x = View.Apply f x

View.Apply的类型,因此( <*> )的类型为:

    View<'A * 'B> -> View<'A> -> View<'B>