2016-03-06 42 views
3

我已经从Railway oriented programming复制验证模块,在我的应用程序执行的错误处理:编译错误Kleisli组合物

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 

据我的理解,validation1validation2应该组成,因为它们都是int list -> ValidationResult<int list>类型。然而,我得到了一个编译错误

期待一种类型支持运算符'> =>',但给予函数 类型。您可能会错过某个函数的参数。

我该如何解决这个问题?

+2

你忘了打开ValidationResult吗? –

+0

@FyodorSoikin,来自我的一个愚蠢的错误......没有意识到这很简单。如果你把你的评论作为答案,我会很乐意接受它。谢谢 – rexcfnghk

回答

6

看来你只是忘了open ValidationResult,所以你的构图操作符不在范围内。

对于一个正常的函数,F#会抱怨该符号未定义。但运营商是另一回事。

可以通过两种方式定义运算符:作为独立函数(函数方式)或作为传递给运算符的一种类型(.NET方式)的静态成员。在前一种情况下,函数需要在作用域中可见,但在后一种情况下它不会:只要您设法将运算符定义为静态成员的对象得到保留,则不需要其类型可见。

这就是为什么F#表示它“期望类型支持运算符”而不是“函数未定义”。