我最近写了一个ETL,工作得很好。
我想提醒自己如何使用免费单子,所以想转换我的ETL。
注意:我在这里的目的不是写一个更好的ETL,而是让自己重新熟悉免费的monads。在重新学习自由单子是如何工作的过程中,我偏离了这个问题的主题。
所以我问
related question
几个月前。有人评论说,我的递归函数可以使用连续传递样式进行尾部递归。我不知道怎么做。
一些示例代码:
type In1 = int
type In2 = int
type Out1 = int
type Out2 = int
type FaceInstruction<'a> =
| Member1 of (In1 * (Out1 -> 'a))
| Member2 of (In2 * (Out2 -> 'a))
let private mapI f = function
| Member1 (x, next) -> Member1 (x, next >> f)
| Member2 (x, next) -> Member2 (x, next >> f)
type FaceProgram<'a> =
| Free of FaceInstruction<FaceProgram<'a>>
| Pure of 'a
let rec bind f = function
| Free x -> x |> mapI (bind f) |> Free
| Pure x -> f x
我想让尾巴重现的功能是
bind
我的尝试看起来像
let rec bind2 (f: 'a -> FaceProgram<'b>) k z : FaceProgram<'b> =
match z with
|Pure x -> x |> f |> k
|Free x -> bind2 ???
我开始认为,事实上,这条尾巴是不可能递归的。类型
FaceInstruction<'a>
已经包含一个continuation,并且函数
mapI
修改该延续,因此现在尝试添加另一个延续
k
是我现在无法处理的两个连续剧之一!