【问题标题】:Why does the parameter b have a type a in this example?为什么这个例子中参数 b 的类型是 a?
【发布时间】:2017-07-14 19:09:49
【问题描述】:

我正在调查 aether library 并注意到了这一点

 type Lens<'a,'b> =
    ('a -> 'b) * ('b -> 'a -> 'a)

 static member (^=) (Set, (_, s): Lens<'a,'b>) =
            fun (b: 'b) ->
                s b : 'a -> 'a

在 ^= 函数中,b 参数 if 是 lambda 中的 'b 类型。但是,在lamda体内,为什么b类型现在是'a?

【问题讨论】:

  • 你为什么这么认为?
  • @FoggyFinder 我不确定。这就是我问的原因。
  • 我的意思是你为什么认为b 有类型'a?顺便说一句,我们可以继续F# chat吗?

标签: f#


【解决方案1】:

但是,在lamda体中,为什么b类型现在是'a?

不是。

b 是一个输入,输入为'b,如fun (b: 'b) -&gt; 所示。

我们可以在没有匹配项的情况下重写该成员,并使用本地定义的函数,如下所示:

static member (^=) (Set, lens: Lens<'a,'b>) =
    // Pattern match to extract out the 2nd portion of the lens, which is a function: 'b -> 'a -> 'a
    let (_,s) = lens

    // Define a function that takes a 'b and returns a new function of type: 'a -> 'a
    let fn (b: 'b) : 'a -> 'a =
        s b // this just partially applies s with the input "b"
    fn // Return the function

基本上,参数列表中的(Set, (_,s)) 将“s”绑定到Lens&lt;'a,'b&gt; 或类型为('b -&gt; 'a -&gt; 'a) 的函数的第二部分。上面,我已经把它分解得更明确,并在它自己的绑定中完成了这个提取。

然后该成员返回一个本地定义的函数(作为 lambda)。在上面,我使用 let 绑定函数重写了它,因为它通常更清晰。

【讨论】:

  • 现在说得通了。忘记了柯里化/部分应用。你知道他们为什么会在这种情况下使用部分应用吗?
  • 还有Set参数需要什么?
【解决方案2】:

我认为您只是误读了语法。代码s b : 'a -&gt; 'a 并不意味着b'a 类型。

正确的阅读方式是把它分成两部分:冒号之前的部分是表达式,冒号之后的部分是表达式的类型。

所以代码s b : 'a -&gt; 'a 实际上意味着s b 的类型是'a -&gt; 'a。它没有单独说明 sb 的类型。

【讨论】:

  • 感谢您的回答。所以 s b 返回一个返回类型 a 的 lamda?
  • 谢谢!现在回看一下,我不知道我是怎么错过这么基本的东西的,哈哈
猜你喜欢
  • 2011-07-23
  • 2012-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-14
相关资源
最近更新 更多