b -> c) -> b -> a -> c > let fl-6ren">
gpt4 book ai didi

haskell - F# 错误 : "Either make the arguments to ' it' explicit or, 如果您不打算将其通用,请添加类型注释。”

转载 作者:行者123 更新时间:2023-12-01 22:55:26 25 4
gpt4 key购买 nike

在 F# 交互式 shell dotnet fsi 中,我正在尝试像在 Haskell 中一样测试 flip 函数,

翻转::(a -> b -> c) -> b -> a -> c

> let flip = fun f -> fun a -> fun b -> f(b)(a);;
val flip: f: ('a -> 'b -> 'c) -> a: 'b -> b: 'a -> 'c

然后,调查内置管道运算符,

> (|>);;
val it: ('a -> ('a -> 'b) -> 'b)

到目前为止还不错。

现在,

> flip (|>);;

flip (|>);;
^^^^^^^^^

/..... : error FS0030: Value restriction. The value 'it' has been inferred to have generic type
val it: (('_a -> '_b) -> '_a -> '_b)
Either make the arguments to 'it' explicit or, if you do not intend for it to be generic, add a type annotation.

谁能解释一下 F# 类型系统中的这个错误是怎么回事?

对我来说,

val it: (('_a -> '_b) -> '_a -> '_b) 实际上应该是预期的结果,我该如何解决这个问题?谢谢。

最佳答案

我的 previous answer解释什么是值(value)限制及其发生的原因。但现在你的下一个问题是:好的,那我该怎么办?

正如错误消息本身所暗示的那样,有两种可能的方法:(1) 为其提供显式参数或 (2) 如果您不希望它是通用的,请添加类型注释。

1。显式参数

let flippedPipe x = flip (|>) x

虽然逻辑上这与 let flippedPipe = flip (|>) 相同,但在句法上这现在是一个函数,而不是一个值。语法对值限制很重要。

2。一个类型注解

let flippedPipe : (int -> int) -> int -> int = flip (|>)

这是可行的,因为该函数不再是通用的,因此值限制不适用。在许多情况下,这是一个理想的选择,但从您在这里使用的函数种类来看,我认为这不是您在这种情况下想要的。

3。显式类型参数

错误消息没有提到这一点,公平地说,它可以被认为是选项 (2) 的变体。这个想法是你可以像这样给你的函数显式类型参数:

let flippedPipe<'a, 'b> = flip (|>)

这使得值限制消失了,因为尽管它在技术上仍然适用,但您添加类型参数的事实大概表明您知道自己在做什么,因此编译器会关闭。

然而,虽然乍一看这似乎有效,但它的实现方式是错误的。如果查看此函数的推断类型,您会看到:

val flippedPipe : (obj -> obj) -> obj  -> obj

发生这种情况是因为,即使您添加了类型参数,您也没有指定它们的确切位置。对于所有编译器所知,它们可能根本不会被使用(也称为“幻像类型”)。

所以要让它正常工作,应该这样定义:

let flippedPipe<'a, 'b> : ('a -> 'b) -> 'a -> 'b = flip (|>)

关于haskell - F# 错误 : "Either make the arguments to ' it' explicit or, 如果您不打算将其通用,请添加类型注释。”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73389055/

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