对于我在F#中取得的所有进展,我仍然迷失在各种构造函数和解构函数语法中 .
我正在运行递归模拟 . 其中一个参数是停止条件的函数 . 我有各种可能的停止条件可供选择 . 我让它们都有相同的签名 . 所以我认为将这些函数锁定为自定义类型会很好,也很有教育意义 - 这样就不会发送任何匹配签名的函数了:
type StoppingCondition = | StoppingCondition of (ReturnType -> ReturnType -> int -> float -> bool)
我认为我正在这样做,从教程,具有类型名称和相同的构造函数名称(令人困惑的......),对于单个案例区分联合 . 但现在我无法弄清楚如何将这种类型应用于实际函数:
let Condition1 lastRet nextRet i fl =
true
如何使Condition1成为StoppingCondition类型?我打赌这是微不足道的 . 但是我尝试将StoppingCondition作为let之后的第一个,第二个或最后一个术语,无论有没有parens和冒号 . 一切都是错误的 .
感谢您在这里找到的耐心 .
编辑:
我将尝试综合我从四个答案中得到的东西(截至当下),一切都很好:
试图模仿这种模式:
s : string = "abc"
我试着写:
type StoppingCondition = | StoppingCondition of (ReturnType -> ReturnType -> int -> float -> bool)
let condition1 lastRet nextRet i fl : StoppingCondition = // BAD
//wrong for a type alias, totally wrong for a union constructor
true
//or
let condition1 : StoppingCondition lastRet nextRet i fl = // BAD again
true
或者 : Stopping Condition 的其他插入(尝试以构造函数的方式作为前缀,在那一行中) .
现在我知道要获得我所得到的东西,我必须这样做:
type StoppingCondition = | StoppingCondition of (ReturnType -> ReturnType -> int -> float -> bool)
let conditionFunc1 lastRet nextRet i fl = //...
true
let stoppingCondition1 = StoppingCondition conditionFunc1
//or
let stoppingCondition2 = StoppingCondition false)
//and there's another variation or 2 below
而我并不认为这种方法的一个重大缺点是联合类型与类型别名的不同之处 . 类型别名 of string 在声明时承认字符串函数 - 它实际上是一个字符串并且“字符串事物 . 单个案例区分联合 of string - 不再是字符串 . 要让它做"string things",你必须打开它 . (或者将这些函数的版本写入你的类型(可能是字符串函数的包装) . )同样,我的函数的类型别名接受这些参数 . 我的函数的DU只是一个包装器,并且不会使用有区别的联合:
let x = stoppingCondition1 ret1 ret2 2 3.0 // BAD
//"stoppingCondition1 is not a function and cannot be applied"
在我的案例中,没有足够的 Value 来解决包装问题 . 但是类型别名有效:
type StoppingAlias = ReturnType -> ReturnType -> int -> float -> bool
let stoppingCondition:StoppingAlias = fun prevRet nextRet i x -> true
let b = stoppingCondition ret1 ret2 10 1.0 // b = true
在我刚才所说的内容中,我可能没有一切,但我认为我更接近 .
编辑2:
边注 . 我的问题是关于定义函数的类型 . 它使用类型别名和联合类型进行比较 . 当我努力做到这些时,我也学会了使用类型别名:
type Adder = decimal -> decimal -> decimal
let f1 : Adder = (fun x y -> x + y)
//or
let f2 : decimal -> decimal -> decimal = fun x y -> x + y
但这些都是错的:
let (f2 : Adder) x y = x + y // bad
let (f3 x y) : (decimal -> decimal -> decimal) = x + y // bad
let (f3 : (decimal -> decimal -> decimal)) x y = x + y // bad
(而且,是的,“分配类型”也不是正确的说法 . )