gpt4 book ai didi

f# - 无点函数/闭包和类型泛型之间的困境?

转载 作者:行者123 更新时间:2023-12-04 05:23:50 25 4
gpt4 key购买 nike

type Alignment =
| Horizontal
| Vertical

let getMainAttr = function
| Horizontal -> fst
| Vertical -> snd

let check alignment =
let mainAttr = getMainAttr alignment
mainAttr (2,3) |> ignore
mainAttr (2.0, 3.0) // error

val getMainAttr : _arg1:Alignment -> ('a * 'a -> 'a)
mainAttr : (int * int -> int) // because of the value restriction

似乎使其通用的唯一方法是使其明确,例如 let mainAttr x = getMainAttr alignment x
但是,因此它不再使用闭包,因此每次 mainAttr被称为 alignment必须检查。

有没有办法只查 alignment一次以及通用?

最佳答案

正如@Daniel 描述的那样,您遇到了值限制限制,该限制不允许创建作为某些 F# 计算结果的通用值(即使该值是一个函数)。您可以在 other SO questions 中找到有关此的更多信息,并且还有一个 article about advanced points 。这种限制的原因是泛型值会在类型安全中引入漏洞。

在您的示例中,您不必担心,因为重复执行 getMainAttr 函数不会增加那么多开销。如果该函数进行了更复杂的计算,您可以返回一个带有通用方法的接口(interface)(而不是一个简单的函数):

/// Interface with as single generic function that selects element of a pair
type PairSelector =
abstract Invoke<'T> : 'T * 'T -> 'T

// Two possible implementations of the interface
let first = { new PairSelector with member x.Invoke(a, b) = a }
let second = { new PairSelector with member x.Invoke(a, b) = b }

// Return a non-generic `PairSelector` value instead of a generic function
let getMainAttr = function
| Horizontal -> first
| Vertical -> second

// Now we can get `PairSelector` value and call it with different type arguments
let check alignment =
let mainAttr = getMainAttr alignment
mainAttr.Invoke (2,3) |> ignore
mainAttr.Invoke (2.0, 3.0)

关于f# - 无点函数/闭包和类型泛型之间的困境?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13419882/

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