我已尽一切努力使编译器能够监听。但是,它拒绝理解。我正在尝试比较每个元素的颜色值,如果它们相同,则返回true,否则返回false。
我放置了想要的约束,但仍然无法确定类型。
let all_same_color cs =
let mutable d=true
let (col:Color) = card_color (cs.Head:Card)
for i in cs do
let col=card_color i
if not (col = col) then
printfn "Black"
d<-false
else
d<-d
printfn "Val %b" d
d
Run Code Online (Sandbox Code Playgroud)
我希望如果颜色匹配则返回true,否则返回false。
它在这一行不断出错:
let (col:Color) = card_color (cs.Head:Card)
Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this programpoint to constrain the type of the object. This may allow the lookup to be resolved.
Run Code Online (Sandbox Code Playgroud)
编译器反对的是cs.Head表达式,因为它无法从该表达式中得知类型cs是什么。它可能是Cards 的列表,但也可能是任何其他具有Head成员的类:在代码中,F#无法分辨是什么cs。(稍后for i in cs do ... card_color i,这足以识别的类型cs,但是F#的编译器是单遍编译器,因此在遇到F#时,cs.Head它还没有关于的类型的任何其他类型提示cs。)
cs在函数定义中定义类型,如下所示:
let all_same_color (cs : Card list) =
// ...
Run Code Online (Sandbox Code Playgroud)
这样就足够了。或者,您也可以替换cs.Head为List.head cs,这也足以让F#编译器确定以下类型cs:
let col = card_color (List.head cs)
Run Code Online (Sandbox Code Playgroud)
你会注意到,现在,就没有必要指定List.head cs是一个Card,或者说col是Color,因为函数签名card_color允许F#推测这一切,。
顺便说一句,通过使用List.map和,还有一种更简单的方法来确定您的卡片列表是否全部相同颜色List.distinct:
let allSameColor cs =
let distinctColors = cs |> List.map card_color |> List.distinct
List.length distinctColors = 1
Run Code Online (Sandbox Code Playgroud)
两行(甚至可以很容易地变成一行,但我想在两行上写起来会更简单),它们与您的原始all_same_color函数具有相同的功能(请注意,我在函数名称中使用了camelCase,因为camelCase是F#函数名称的常规约定)。唯一的区别是您的功能有副作用(打印“黑色”或“ Val :(某物)”),而我故意编写了“纯”,无副作用的功能。每个函数只做一件事是一个好习惯:要么返回一个值,要么有副作用,但不能两者都做。
| 归档时间: |
|
| 查看次数: |
57 次 |
| 最近记录: |