我正在尝试在 F# 中实现 Clojure 转换器,并很快遇到了可怕的值限制错误。
Transducers 的重点是可组合的。这是一些示例代码:
type Reducer<'a,'b,'c> = ('a -> 'b -> 'a) -> 'a -> 'c -> 'a
module Transducers =
[<GeneralizableValue>]
let inline map proj : Reducer<'result,'output,'input> =
fun xf ->
fun result input ->
xf result (proj input)
let inline conj xs x = x :: xs
let inline toList xf input = List.fold (xf conj) [] input
let xform = map (fun i -> i + 9) >> map (fun a -> a * 5)
//let xs = toList xform [1;2] // if you apply this, type will be fixed to 'a list
// which makes xform unusable with eg 'a seq
GeneralizableValue
应该解除价值限制,但似乎什么也没做。您的任务是在不应用的情况下编译此代码toList
(类型推断会将类型固定为'a list
,因此您不能将相同的 xform 与 a 一起使用seq
)并且不更改 xform 的类型(至少不会以某种方式使其不可组合)。这在 F# 中根本不可能吗?