gpt4 book ai didi

F# 柯里化(Currying)函数的类型不匹配

转载 作者:行者123 更新时间:2023-12-02 07:53:53 25 4
gpt4 key购买 nike

我在使用以下 FSharp/F# 代码时遇到了一些问题:

module File1

let api a =
printf ("VALUE = %A") a

let router ops =
[|
api (ops (fun (list, _) -> list()))
api (ops (fun (_, get) -> get 1))
|]

let withContext ops handler =
let context = "CONTEXT"
handler (ops context)

let operations context =
printf ("CONTEXT = %s") context

let list () = [|1;2;3|]
let get id = "Test"
(list, get)

let setup() =
let ops = withContext operations
router ops

导致以下错误

Results in the following compation error
Error 1 Type mismatch. Expecting a
((unit -> int []) * (int -> int []) -> int []) -> 'a
but given a
((unit -> int []) * (int -> string) -> 'b) -> 'b
The type 'int []' does not match the type 'string'

我知道问题是 ops 函数已绑定(bind)返回 int[],但我希望也能够返回字符串。

我认为我错过了一些通用声明的技巧,但经过几个小时的移动代码后,我似乎无法解决它。

(我简化了代码以突出显示我的问题)

最佳答案

该错误是因为 ops 需要在编译时解析其 handler 的返回类型,并且您希望根据某些运行时逻辑返回不同的类型。

它基本上相当于:

let fun1 switch arg2 arg3 =
if switch then
arg2
else
arg3

你想这样运行它:

fun1 true 1 "string"

当然,arg2和arg3需要具有相同的类型,所以它不起作用

您可以做的是在返回处理程序结果之前运行“api”函数(因此它始终是相同的类型 - 单位)。

let router ops =
[|
ops (fun (list, _) -> api <| list()))
ops (fun (_, get) -> api <| get 1))
|]

或者,您可以返回有区别的联合类型的对象(然后您将需要 api 函数中更多的逻辑)。

(从技术上讲,您也可以返回 obj)。

奖金

您不需要在 router 函数中返回单元数组,返回一个单元就可以了:

let router ops =
ops (fun (list, _) -> api <| list()))
ops (fun (_, get) -> api <| get 1))

这样,setup函数也会返回unit,您将能够运行它,而无需在ignore上运行结果摆脱此表达式应具有类型“unit”,但具有类型“unit[]”警告。

关于F# 柯里化(Currying)函数的类型不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35553315/

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