gpt4 book ai didi

generics - 如何在 F# 中做一个 Applicative?

转载 作者:行者123 更新时间:2023-12-04 18:03:20 26 4
gpt4 key购买 nike

给定以下类型和成员函数

type Result<'TSuccess, 'TError> = 
| Success of 'TSuccess
| Error of 'TError list
with
member this.apply fn =
match (fn, this) with
| Success(f), Success(x) -> Success(f x)
| Error(e), Success(_) -> Error(e)
| Success(_), Error(e) -> Error(e)
| Error(e1), Error(e2) -> Error(List.concat [e1;e2])

以及以下内联函数
let inline (<*>) (f: ^A) (t:^A) = 
let apply' = (^A : (member apply : ^A -> ^A) (t, f))
apply'

还有这个调用站点
let y () = Success (fun x -> x + 1) <*> (Success 3)

我收到以下错误
 let y () = Success (fun x -> x + 1) <*> (Success 3);;
-----------^^^^^^^^^^^^^^^^^^^^^^^^
/Users/robkuz/stdin(473,12): error FS0001: Type constraint mismatch.
The type
Result<'a,'c>
is not compatible with type
Result<('a -> 'b),'c>
The resulting type would be infinite when unifying ''a' and ''a -> 'b'

这整个事情是试图模仿 Haskell Applicative 并且签名应该是
(<*>) :: forall f a b. Apply f => f (a -> b) -> f a -> f b

但我不认为在 F# 中无法表达

关于如何做到这一点的任何想法?

最佳答案

一般来说,我认为尝试在 F# 中模拟 Haskell 模式并不是一个好主意。在 Haskell 中,许多代码被编写为非常通用的,因为 monad 和应用程序被更频繁地使用。

在 F# 中,我更喜欢编写更专业的代码,因为您不需要在 monad 或 applicative 上编写多态代码,它只是让您更容易了解发生了什么。所以,我不认为我会想写 <*>在 F# 中的实践中适用于任何“应用”的运算符。

也就是说,您的代码的问题在于 <*>运算符使用相同的 ^A参数和结果的类型参数(虽然它们在调用中是不同的类型) - 如果您使用三个单独的类型参数,它可以正常工作:

let inline (<*>) (f: ^B) (t:^A) : ^C = 
let apply' = (^A : (member apply : ^B -> ^C) (t, f))
apply'

关于generics - 如何在 F# 中做一个 Applicative?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37949413/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com