我有一个从Railway oriented programming复制的验证模块,它在我的应用程序中执行错误处理:
type ErrorMessage = ErrorMessage of string
type ValidationResult<'T> =
| Success of 'T
| Error of ErrorMessage
module ValidationResult =
let doubleMap successHandler errorHandler = function
| Success x -> successHandler x
| Error e -> errorHandler e
let bind f = function
| Success x -> f x
| Error e -> Error e
let (>=>) f g = f >> bind g
我正在使用以下测试功能测试Kleisli成分:
let validation1 (list: int list) =
if List.length list = 6
then Success list
else Error <| ErrorMessage "Length error"
let validation2 list =
if List.forall (fun x -> x > 6) list
then Success list
else Error <| ErrorMessage "All elements must be larger than 6"
let combined = validation1 >=> validation2
//^^^^^^^^^^^^ compile error
据我了解,validation1
和validation2
应构成,因为它们都属于int list -> ValidationResult<int list>
类型。但是我收到了编译错误
期望支持运营商的类型'&gt; =&gt;'但是给了一个功能 类型。您可能缺少函数的参数。
我该如何解决这个问题?
答案 0 :(得分:6)
您似乎忘记了open ValidationResult
,因此您的合成运算符不在范围内。
对于正常功能,F#会抱怨该符号未定义。但运营商是另一回事。
可以通过两种方式定义运算符:作为独立函数(函数方式)或作为传递给运算符的类型之一的静态成员(.NET方式)。在前一种情况下,函数需要在范围内可见,但在后一种情况下它并不是:只要你设法获得一个操作符被定义为静态成员的对象,你就不会这样做。需要让它的类型可见。
这就是为什么F#说它&#34;期望一个类型支持运营商&#34;而不是&#34;功能未定义&#34;。