gpt4 book ai didi

Haskell MultiParamTypeClasses 和 UndecidableInstances

转载 作者:行者123 更新时间:2023-12-02 18:08:28 27 4
gpt4 key购买 nike

我是 Haskell 新手,只是玩了一段时间。

我编写了一个轻量级的 OOP 模拟:

 --OOP.hs
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, UndecidableInstances, ScopedTypeVariables, FunctionalDependencies #-}

module OOP where
class Provides obj iface where
provide::obj->iface
(#>)::obj->(iface->a)->a
o #> meth = meth $ provide o

class Instance cls obj | obj -> cls where
classOf::obj->cls

class Implements cls iface where
implement::(Instance cls obj)=>cls->obj->iface

instance (Instance cls obj, Implements cls iface)=>Provides obj iface where
provide x = implement (classOf x::cls) x

像这样使用它:

 --main.hs
{-# LANGUAGE MultiParamTypeClasses #-}

import OOP
data I1 = I1
getI1::I1->String
getI1 i1 = "Interface 1"

data I2 = I2
getI2::I2->String
getI2 i2 = "Interface 2"


data C = C


instance Implements C I1 where
implement C o = I1

instance Implements C I2 where
implement C o = I2

data O = O
instance Instance C O where
classOf o = C

main = do
putStrLn (O #> getI1)
putStrLn (O #> getI2)

我读到 UndecidableInstances 功能非常不方便,并且可能导致 stack overflows在编译器中。所以我有两个问题。

  1. 能否改进此代码,保持易用性以及实例和类数据类型之间以及接口(interface)和类之间的1 到 N 关系?
  2. 是否可以使用单参数类型类实现类似的逻辑?

最佳答案

在这种情况下,您使用不可判定的实例是可以的。

instance (Instance cls obj, Implements cls iface)=>Provides obj iface where

是不可判定的,因为您可能有一个 InstanceImplements 的实例,而这些实例又依赖于 Provides 导致循环。

但是,在这种情况下,您根本不需要 Provides 类,因为您只根据其他两个类的方法给出它的实现!

您可以将 provides#> 拉出为具有适当 InstanceImplements 的顶级函数> 约束,你不会失去任何东西,并且避免了对不可判定实例的需要。

但是,您确实需要/想要 MPTC,这很好......

关于Haskell MultiParamTypeClasses 和 UndecidableInstances,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21216861/

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