F# Monad 如何修复数据类型
F# Monad how fix datatypes
我正在尝试用 F# 编写一个 Monad,但我无法编译代码并且出现错误 FS0001
错误:此表达式的类型应为 'Result' 但此处的类型为 '(Result<'a> -> Result<'b>) -> Result<'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
首先你的bind
类型不对:
your version : Result<'a> -> (Result<'a> -> Result<'b>) -> Result<'b>
typical type : Result<'a> -> ('a -> Result<'b>) -> Result<'b>
如果你把参数的顺序调换一下得到:
bind : ('a -> Result<'b>) -> Result<'a> -> Result<'b>
因此,您可以使用以下 bind
:
let bind f x =
match x with
| Success x -> f x
| Failure -> Failure
执行此操作后,您可以定义 bindIsPositive
和 bindToString
。 bind
操作现在将一个函数作为第一个参数,所以这可行,但你必须删除你的类型注释:
let bindIsPositive = bind isPositive
let bindToString = bind toString
编写函数时,您可以使用 >>=
运算符,或使用普通的 F# 管道和 bind
函数:
let strintToIntIsPositiveIntToString x = x |> stringToInt |> bindIsPositive |> bindToString
let strintToIntIsPositiveIntToString x = x >>= stringToInt >>= isPositive >>= toString
我正在尝试用 F# 编写一个 Monad,但我无法编译代码并且出现错误 FS0001 错误:此表达式的类型应为 'Result' 但此处的类型为 '(Result<'a> -> Result<'b>) -> Result<'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
首先你的bind
类型不对:
your version : Result<'a> -> (Result<'a> -> Result<'b>) -> Result<'b>
typical type : Result<'a> -> ('a -> Result<'b>) -> Result<'b>
如果你把参数的顺序调换一下得到:
bind : ('a -> Result<'b>) -> Result<'a> -> Result<'b>
因此,您可以使用以下 bind
:
let bind f x =
match x with
| Success x -> f x
| Failure -> Failure
执行此操作后,您可以定义 bindIsPositive
和 bindToString
。 bind
操作现在将一个函数作为第一个参数,所以这可行,但你必须删除你的类型注释:
let bindIsPositive = bind isPositive
let bindToString = bind toString
编写函数时,您可以使用 >>=
运算符,或使用普通的 F# 管道和 bind
函数:
let strintToIntIsPositiveIntToString x = x |> stringToInt |> bindIsPositive |> bindToString
let strintToIntIsPositiveIntToString x = x >>= stringToInt >>= isPositive >>= toString