我正在尝试用F#写一个Monad但是我无法编译代码而且我收到错误FS0001错误:这个表达式预计会有类型'Result'但是这里有类型'(Result <'a> - > Result << b>) - >结果<'b>'
open System
type Result<'TSuccess> =
| Success of 'TSuccess
| Failure
let bind x f =
match x with
| Success x -> f (Success x)
| Failure -> Failure
let stringToInt (s:string) =
try
let result = s |> int
Success result
with
|_-> Failure
let isPositive (i:int) =
if ( i > 0) then Success i : Result<int>
else Failure
let toString (i:int) =
try
let result = i |> string
Success result
with
|_ -> Failure
let bindIsPositive = bind isPositive : Result<int>
let bindToString = bind toString : Result<string>
let (>>=) x f = bind f x
let strintToIntIsPositiveIntToString s = stringToInt >>= bindIsPositive >>= bindToString
[<EntryPoint>]
let main argv =
printfn "10"
let mys = strintToIntIsPositiveIntToString "9"
Console.WriteLine mys.ToString
0 // return an integer exit code
Run Code Online (Sandbox Code Playgroud)
首先,你的类型bind
是不对的:
your version : Result<'a> -> (Result<'a> -> Result<'b>) -> Result<'b>
typical type : Result<'a> -> ('a -> Result<'b>) -> Result<'b>
Run Code Online (Sandbox Code Playgroud)
如果你改变参数的顺序,那么完成剩下的工作也会容易得多:
bind : ('a -> Result<'b>) -> Result<'a> -> Result<'b>
Run Code Online (Sandbox Code Playgroud)
因此,您可以使用以下内容bind
:
let bind f x =
match x with
| Success x -> f x
| Failure -> Failure
Run Code Online (Sandbox Code Playgroud)
完成此操作后,您可以定义bindIsPositive
和bindToString
.该bind
操作现在将函数作为第一个参数,因此这可以工作,但您必须删除类型注释:
let bindIsPositive = bind isPositive
let bindToString = bind toString
Run Code Online (Sandbox Code Playgroud)
在编写函数时,您可以使用>>=
运算符,也可以使用普通的F#管道和bind
函数:
let strintToIntIsPositiveIntToString x = x |> stringToInt |> bindIsPositive |> bindToString
let strintToIntIsPositiveIntToString x = x >>= stringToInt >>= isPositive >>= toString
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
77 次 |
最近记录: |