【问题标题】:function merging / combinator in fsharpfsharp 中的函数合并/组合器
【发布时间】:2012-02-23 10:18:28
【问题描述】:

我有一个函数列表,接受相同类型作为输入,不同类型作为输出

 [ f_i :  Mytype -> res:Sometype_i ] 

哪个操作可以将它们合并为以下类型的一个函数?

 f : Mytype -> \Product_i Mytype_i

同样,如果我有一个返回相同类型的函数列表

 [ f_i : Mytype_i -> res:Sometype ] 

哪个操作可以将它们合并为以下类型的一个函数?

 f : \Product_i Mytype_i ->  Mytype list

这将是一些规范的“preCombinator”或“postCombinator”。 (我想它在 FP 中有一个名字..)

【问题讨论】:

  • 我不明白你的意思 - 你的语法不是 F# - 特别是 func 不是 F# 关键字,也惯用 F# 写 int list 而不是 [int] 这令人困惑(我认为这就是你的意思)
  • 对不起,我对 fsharp 语法不太熟悉。我想您必须删除 func 才能将 fsahrp 输出为类型。我会编辑它。
  • 如果您使用 F# 交互,它会为您打印出类型签名,这可以帮助您解决此类问题,如果您使用编译器,也可以使用 --sigfile 选项

标签: f# functional-programming combinators


【解决方案1】:

您的第一个问题的答案是您一般不能这样做。列表是具有动态长度的数据结构,但生成的元组的长度必须在编译时静态知道。 (您可以使用反射构造结果元组并将其用作obj,但这并不是真正有用。)

在第二种情况下,您希望将函数列表转换为函数返回列表,这可以做到(两者都具有动态长度)。你可以这样写:

let funcs =
  [ (fun n -> n + 1)
    (fun n -> n * 2) ]

let merged =
  funcs |> List.fold (fun agg f ->
    fun inp -> (f inp)::(agg inp)) (fun _ -> [])

原始操作(传递给fold)是一个函数,它采用TInp -> TOut list 类型的函数和TInp -> TOut 类型的函数,并将它们组合成一个返回更长列表的函数。所以你也可以写:

// val addResult : ('a -> 'b list) -> ('a -> 'b) -> 'a -> 'b list  
let addResult agg f inp = (f inp)::(agg inp)

// val merge : ('a -> 'b) list -> ('a -> 'b list)
let merge funcs = funcs |> List.fold addResult (fun _ -> [])

【讨论】:

  • 是的,我想我可以自己写,但我认为会有一些内置的组合器。至少它是非常有教育意义的!
  • 非常正确,类型本身正在发生变化。只有进入无类型的“obj”世界才有可能……有趣的是,此时我已经投入其中,因为我进行了反思以自动为我的记录字段创建设置器。现在,如果我想从各个字段设置器为我的整个结构创建一个设置器,我不能静态地做到这一点。这是我见过很多很多次的混合问题。反射世界打破了类型。
  • 这是因为反射来自更高的“运行时级别”,我们在运行时“级别 0”的类型环境中使用运行时“级别 -1”。类型提供者很好地解决了这个问题:我们可以表达这个问题,它本质上是“级别 -1”,因为我们想要动态映射,但是我们运行它来为“级别 0”提供类型,并且这个级别确实混合了它自己的类型生成level,即“level -1”,使用此类类型,即“level 0”
  • 再说一次,这是我见过很多很多次的问题。 (我相信解决方案会通过这个运行时级别的想法,但这是另一回事)
【解决方案2】:

Tomas 针对第二个问题的解决方案的替代方案,其额外的好处是按照最初的顺序返回函数

let funcs =
  [ (fun n -> n + 1)
    (fun n -> n * 2) ]

let merged = fun input -> funcs |> List.map (fun f -> f input)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-16
    • 2021-06-06
    • 2018-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多