gpt4 book ai didi

f# - 了解 F# 值限制错误

转载 作者:行者123 更新时间:2023-12-01 08:05:19 25 4
gpt4 key购买 nike

我不明白 F# 中的值限制是如何工作的。我已经阅读了 wiki 中的解释以及 MSDN documentation .我不明白的是:

  1. 为什么,例如,这会给我一个值限制错误(摘自 this 问题):

    let toleq (e:float<_>) a b = (abs ( a - b ) ) < e

    但事实并非如此:

    let toleq e (a:float<_>) b = (abs ( a - b ) ) < e
  2. 这是普遍化的好吧...

    let is_bigger a b = a < b

    但这不是(它被指定为 int):

    let add a b = a + b
  3. 为什么带有隐式参数的函数会产生值限制:

    这个:

    let item_count = List.fold (fun acc _ -> 1 + acc) 0

    对比这个:

    let item_count l = List.fold (fun acc _ -> 1 + acc) 0 l

    (请注意,如果我确实在代码片段中使用了这个函数,VR 错误就会消失,但是函数将被指定为我使用它的类型,我希望它被泛化)

它是如何工作的?

(我使用的是最新的 F#,v1.9.6.16)

最佳答案

编辑

更好/最近的信息在这里:Keeping partially applied function generic

(以下为原文)

我认为这里务实的做法是不要试图深入理解这一点,而是要了解一些通用策略以通过 VR 并继续您的工作。这是一个有点“逃避”的答案,但我不确定在这里花时间了解 F# 类型系统的内部结构(从一个版本到另一个版本,它会继续以微小的方式发生变化)是否有意义。

我提倡的两个主要策略是这些。首先,如果您使用函数类型定义一个值(类型带有箭头“->”),则通过执行 eta-conversion 确保它是一个句法函数。 :

// function that looks like a value, problem
let tupleList = List.map (fun x -> x,x)
// make it a syntactic function by adding argument to both sides
let tupleList l = List.map (fun x -> x,x) l

其次,如果您仍然遇到 VR/泛化问题,请指定整个类型签名来说明您想要的内容(然后在 F# 允许的情况下“退出”):

// below has a problem...
let toleq (e:float<_>) a b = (abs ( a - b ) ) < e
// so be fully explicit, get it working...
let toleq<[<Measure>]'u> (e:float<'u>) (a:float<'u>) (b:float<'u>) : bool =
(abs ( a - b ) ) < e
// then can experiment with removing annotations one-by-one...
let toleq<[<Measure>]'u> e (a:float<'u>) b = (abs ( a - b ) ) < e

我认为这两种策略是最实用的建议。也就是说,这是我尝试回答您的具体问题。

  1. 我不知道。

  2. '>' 是一个完全通用的函数 ('a -> 'a -> bool),适用于所有类型,因此 is_bigger 具有泛化性。另一方面,“+”是一个“内联”函数,适用于少数基本类型和其他类型的某个类;它只能在其他“内联”函数中泛化,否则必须固定为特定类型(或默认为“int”)。 (即席多态性的“内联”方法是 F# 中的数学运算符克服“类型类”不足的方式。)

  3. 这就是我上面讨论的“语法功能”问题; '让我们编译成字段/属性,与函数不同,它不能是通用的。因此,如果您希望它是通用的,请将其设为函数。 (另请参阅 this question 了解此规则的另一个异常(exception)情况。)

关于f# - 了解 F# 值限制错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23201186/

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