gpt4 book ai didi

haskell - F#中是否有类似 "rigid type"这样的东西?

转载 作者:行者123 更新时间:2023-12-02 14:16:05 24 4
gpt4 key购买 nike

在Haskell中,类型类可以引入“接口(interface)”,其中有一些“自由”类型参数,例如“对于所有a:实例支持这组函数”。如果你实例化这样的类型类,你就不能缩小这个a类型,否则你会得到关于刚性类型的错误 a (比如“对于所有人,但现在变得更加狭窄,这打破了原始类型对所有人的 promise ”)。好的,我实现了 IEnumerable我的 F# 类型(类)中的接口(interface):

    interface System.Collections.Generic.IEnumerable<byte> with
member __.GetEnumerator () = (__.GetBytes ()).GetEnumerator ()

这正在编译,按我的预期工作,一切都很好。但这里我做了更窄的界面:IEnumerable<byte>而不是IEnumerable<'Any> 。那么,IEnumerable中的类型参数是什么? ?你可以实现更具体、更窄的接口(interface),对吗?它不像 Haskell 中的“forall”,或者?

最佳答案

您的代码片段类似于 Haskell 实例,而不是 Haskell 类。此代码片段表示周围类型是 IEnumerable<byte> 的实例这类似于 instance IEnumerable T Byte在 Haskell 中(其中 T 是您实现 IEnumerable 的类型)。

我想这里的关键见解是 IEnumerable必须被视为一个多参数类型类,其中一个参数表示序列的类型,另一个参数表示序列的元素。

在 F# 中,第一个参数是隐式 - 它没有在接口(interface)声明中直接提及,但每个接口(interface)都有它 - 它是实现接口(interface)的类型。

// F#
type MyType = MyType with
interface IEnumerable<byte> with
member this.GetEnumerator() = xyz


-- Haskell
class IEnumerable t e where
getEnumerator :: t -> [e]

data MyType = MyType

instance IEnumerable MyType Byte where
getEnumerator t = xyz

在这里,很容易看出 te实际上是“刚性”类型。多参数反射(reflect)了相同类型 t 的事实可能有多个 IEnumerable不同的实现e ,同样的方式你可以实现多个具体 IEnumerable<e> F# 中的类型。

F# 不能做的一件事(因此)是为任何 e 提供实现。 ,像这样:

instance IEnumerable MyType e where
getEnumerator t = ...

要在 F# 中实现类似(尽管不相同)的效果,需要创建另一个接口(interface)并实现它:

type AnyEnumerable =
abstract member AnyEnumerate<'a>() : IEnumerable<'a>

type MyType = MyType with
interface AnyEnumerable with
member this.AnyEnumerate<'a>() =
{ new IEnumerable<'a> with
member this.GetEnumerator() = ... }

let x = MyType.AnyEnumerate<int>()
let y = MyType.AnyEnumerate<string>()

关于haskell - F#中是否有类似 "rigid type"这样的东西?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48354646/

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