玩弄F#,我对以下行为感到困惑.何时List.reduce (>>)被注释掉,有错误
defaultLabel |> showRainbow
----------------^^^^^^^^^^^
This expression was expected to have type
CoolLabel -> 'a
but here has type
(CoolLabel -> CoolLabel) list
Run Code Online (Sandbox Code Playgroud)
在这个例子中,来自http://fsharpforfunandprofit.com/posts/conciseness-functions-as-building-blocks/:
// create an underlying type
type CoolLabel = {
label : string;
}
let defaultLabel =
{label="";}
let setLabel msg label =
{label with CoolLabel.label = msg}
let rainbow =
["red";"orange";"yellow";"green";"blue";"indigo";"violet"]
let showRainbow =
rainbow
|> List.map setLabel
|> List.reduce (>>)
// test the showRainbow function
defaultLabel |> showRainbow
Run Code Online (Sandbox Code Playgroud)
什么时候List.reduce (>>)删除,我认为showRainbow应该返回一个CoolLabel列表,编译器会很酷.
编辑 - >(忽略这句话,因为下面的答案改变了我的理解.):"顺便说一句,我得到的List.reduce(>>)会从列表中返回最后一个CoolLabel."
谢谢.
Tom*_*cek 13
通过List.reduce (>>)更改类型来删除行,showRainbow因此您得到的东西不是函数,因此流水线操作符不能将其defaultLabel作为参数调用.
在原始程序中,类型showRainbow是将一个CoolLabel变为另一个的函数:
val showRainbow : (CoolLabel -> CoolLabel)
Run Code Online (Sandbox Code Playgroud)
如果删除线,你会得到一个列表的功能:
val showRainbow : (CoolLabel -> CoolLabel) list
Run Code Online (Sandbox Code Playgroud)
这个例子不是以微不足道的方式使用函数,所以让我解释一下实际上正在发生什么.我们从rainbow哪个颜色列表开始.接下来,rainbow |> List.map setLabel将颜色列表转换为函数列表.你可以这样读:
rainbow |> List.map (fun color -> setLabel color)
Run Code Online (Sandbox Code Playgroud)
但是,setLabel有两个论点.这里我们只指定第一个,因此结果是一个函数,它期望CoolLabel并将其颜色更改为彩虹的当前颜色.
一旦你有了函数列表,就List.reduce (>>)组成它们 - 它构建一个新函数,在它接收的输入上调用它们的所有函数.所以结果基本上是一个功能:
let resultingFunction input =
setLabel "violet" (setLabel "indigo" (setLabel "blue" ( ... (input)))))
Run Code Online (Sandbox Code Playgroud)
现在你可以看到为什么这会返回一个紫罗兰色的标签 - 它将颜色defaultLabel变为红色,然后变为橙色,然后变为黄色等,最后变为靛蓝色,然后变为紫色!
如果你改变setLabel它不会忽略原始颜色,但也许组合它们(通过附加字符串),那么你将看到如何setLabel在所有颜色上调用该函数:
let setLabel msg label =
{ label with CoolLabel.label = label.label + " " + msg }
Run Code Online (Sandbox Code Playgroud)
结果将是:
> defaultLabel |> showRainbow;;
val it : CoolLabel = {label = " red orange yellow green blue indigo violet";}
Run Code Online (Sandbox Code Playgroud)