Haskell 如何定义类型类返回另一类型类的值
我怎么能说单子m是Haskell 如何定义类型类返回另一类型类的值,haskell,Haskell,我怎么能说单子m是 恐怖分子的例子 对于它,ask返回属于类型类的值HasReadables 这样,该类型类又定义了一个函数,该函数返回属于第二个FuncsClass 这样我就可以调用第二个类型类中的函数,FuncsClass e、 g.val解决方案是TypeFamilies扩展 {-# LANGUAGE TypeFamilies #-} 使用它,我们可以将名为FuncsResults的占位符添加到HasReadablestype类声明中,该声明将标识每个实例将返回的具体类型。我们可以约束
- 恐怖分子的例子
- 对于它,
返回属于类型类的值ask
HasReadables
- 这样,该类型类又定义了一个函数,该函数返回属于第二个
FuncsClass
- 这样我就可以调用第二个类型类中的函数,
FuncsClass
- e、 g.
val解决方案是
扩展TypeFamilies
使用它,我们可以将名为{-# LANGUAGE TypeFamilies #-}
的占位符添加到FuncsResults
type类声明中,该声明将标识每个实例将返回的具体类型。我们可以约束此占位符,以确保在实例中选择的任何类型本身都是HasReadables
类的实例Funcs
class Funcs f where func1 :: f -> Int class (Funcs FuncsResult) => HasReadables r where type FuncsResult :: * readable1 :: r -> FuncsResult
下面是具体的数据类型instance Funcs FuncsRepr where func1 = returnValue instance HasReadables Wrapper where type FuncsResult = FuncsRepr readable1 = repr
下面是如何实现这些类,我们现在将占位符data FuncsRepr = FuncsRepr { returnValue :: Int } data Wrapper = Wrapper { repr :: FuncsRepr }
替换为实际的具体类型FuncsResult
,它是FuncsRepr
类的一个实例Funcs
class Funcs f where func1 :: f -> Int class (Funcs FuncsResult) => HasReadables r where type FuncsResult :: * readable1 :: r -> FuncsResult
此占位符的使用修复了先前导致类型推断引擎出错的歧义 最后,这里是一个一元函数示例instance Funcs FuncsRepr where func1 = returnValue instance HasReadables Wrapper where type FuncsResult = FuncsRepr readable1 = repr
并取得了预期的效果monadFunc :: (HasReadables r, MonadReader r m) => String -> m String monadFunc s = do val <- liftM (func1 . readable1) ask return (s ++ show val)
Hello2
解决这个问题的方法是
扩展TypeFamilies
使用它,我们可以将名为{-# LANGUAGE TypeFamilies #-}
的占位符添加到FuncsResults
type类声明中,该声明将标识每个实例将返回的具体类型。我们可以约束此占位符,以确保在实例中选择的任何类型本身都是HasReadables
类的实例Funcs
class Funcs f where func1 :: f -> Int class (Funcs FuncsResult) => HasReadables r where type FuncsResult :: * readable1 :: r -> FuncsResult
下面是具体的数据类型instance Funcs FuncsRepr where func1 = returnValue instance HasReadables Wrapper where type FuncsResult = FuncsRepr readable1 = repr
下面是如何实现这些类,我们现在将占位符data FuncsRepr = FuncsRepr { returnValue :: Int } data Wrapper = Wrapper { repr :: FuncsRepr }
替换为实际的具体类型FuncsResult
,它是FuncsRepr
类的一个实例Funcs
class Funcs f where func1 :: f -> Int class (Funcs FuncsResult) => HasReadables r where type FuncsResult :: * readable1 :: r -> FuncsResult
此占位符的使用修复了先前导致类型推断引擎出错的歧义 最后,这里是一个一元函数示例instance Funcs FuncsRepr where func1 = returnValue instance HasReadables Wrapper where type FuncsResult = FuncsRepr readable1 = repr
并取得了预期的效果monadFunc :: (HasReadables r, MonadReader r m) => String -> m String monadFunc s = do val <- liftM (func1 . readable1) ask return (s ++ show val)
Hello2
“也许我需要考虑的不是类型课”——事实上。看起来很像您尝试(ab)在这里使用类型类作为OO类。不要那样做;将OO类转换为Haskell的正确方法(如果有)是使用函数作为普通数据记录(≌ 方法)作为字段。继承只是一个更新这些字段的问题,这里我考虑的更多的是OCaml的模块系统(mod signature+type+mod实现),而不是OOP。我只是好奇:(a)通过在纯代码中定义业务逻辑,使一元函数尽可能短;(b)将一元代码与底层数据表示中的更改完全隔离开来。我认为这是一个很好的解决方案。给我们一个背景——你真正想要达到的目标——我们就能提供一个更好的解决方案。我在主要问题的编辑中提供了具体的代码(最初我试着在评论中这样做,但不可读,所以我把它们删除了)。是否有不止一件事是
?-或者简单地说:为什么不使用HasLevel
类型/结构呢?(显然,对于<代码>同样的问题,HasBooer-<代码> />代码>播放器< /代码>)“也许我需要考虑除了类型类之外的其他东西”——确实如此。看起来很像您尝试(ab)在这里使用类型类作为OO类。不要那样做;将OO类转换为Haskell的正确方法(如果有)是使用函数作为普通数据记录(≌ 方法)作为字段。继承只是一个更新这些字段的问题,这里我考虑的更多的是OCaml的模块系统(mod signature+type+mod实现),而不是OOP。我只是好奇:(a)通过在纯代码中定义业务逻辑,使一元函数尽可能短;(b)将一元代码与底层数据表示中的更改完全隔离开来。我认为这是一个很好的解决方案。给我们一个背景——你真正想要达到的目标——我们就能提供一个更好的解决方案。我在主要问题的编辑中提供了具体的代码(最初我试着在评论中这样做,但不可读,所以我把它们删除了)。是否有不止一件事是级别
?-或者简单地说:为什么不使用HasLevel
类型/结构呢?(对于级别
/HasPlayer
显然是同一个问题)我一直在等待,看看是否有人能提出这方面的错误,或者更好的解决方案,但既然没有人提出,我就接受我自己的答案。我一直在等待,看看是否有人能提出这方面的错误,或者更好的解决方案,但既然没有人提出,我只接受我自己的答案。Player