问题描述
class(Context(Associated) ab))=>类别a其中
数据关联a :: * - > *
实例上下文(Associated ab)其中
func1 =错误func1
然而,不在范围内的自由变量 b
阻止了我这样做。其中一个解决方案是从 Context
复制类的功能,但它看起来很难看。
class Class a where
data相关a :: * - > *
- 从类Context中复制所有函数
contextFunc1 ::关联a b - >字符串
实例类a =>上下文(Associated ab)其中
func1 = contextFunc1
是否有一种惯用的方式来约束约束在关联的数据类型中有哪些头部没有提到变量?
编辑:我想保持与GHC 7.0.3的兼容性
您可以像这样手动传递字典(使用 Context
= Show
作为示例):
{ - #LANGUAGE ScopedTypeVariables,TypeFamilies,ExistentialQuantification# - }
data ShowDict a = Show a => ShowDict
class Class a where
data相关a :: * - > *
getShow :: ShowDict(关联a b)
- 便捷函数
getShowFor :: Class a =>相关联的b - > ShowDict(Associated a b)
getShowFor _ = getShow
showAssociated :: Class a =>相关联的b - > String
showAssociated a =
case getShowFor a of
ShowDict - > - Show(Associated ab)通过这个模式匹配
显示一个
实例类Int其中
数据Associated Int b = Foo派生Show
getShow = ShowDict
main = print $ showAssociated Foo
这是有点类似于你建议的功能复制,但是它的优点是:
$ b $ ul
$ b
showAssociateds :: forall a。 Class a => [Associated a b] - > String
showAssociateds as =
case getShow :: ShowDict(关联a b)
ShowDict - >
显示为
主要缺点是使用 getShow
总是需要一个明确的类型签名(像 getShowFor
这样的函数可以缓解这个问题)。
I would like to state that the associated data is always an instance of a certain class.
class (Context (Associated a b)) => Class a where
data Associated a :: * -> *
instance Context (Associated a b) where
func1 = error "func1"
However, the free variable b
that is not in scope prevents me from this. One of the solutions is to copy class functions from Context
, but it looks ugly.
class Class a where
data Associated a :: * -> *
-- duplicate all functions from class Context
contextFunc1 :: Associated a b -> String
instance Class a => Context (Associated a b) where
func1 = contextFunc1
Is there an idiomatic way to put constraints on associated data type which has variables not mentioned in head?
edit: I would like to keep compatibility with GHC 7.0.3
I don't have GHC 7.0.3 available, but I think this should work with it.
You could pass the dictionaries around manually like this (using Context
= Show
as an example):
{-# LANGUAGE ScopedTypeVariables, TypeFamilies, ExistentialQuantification #-}
data ShowDict a = Show a => ShowDict
class Class a where
data Associated a :: * -> *
getShow :: ShowDict (Associated a b)
-- Convenience function
getShowFor :: Class a => Associated a b -> ShowDict (Associated a b)
getShowFor _ = getShow
showAssociated :: Class a => Associated a b -> String
showAssociated a =
case getShowFor a of
ShowDict -> -- Show (Associated a b) is made available by this pattern match
show a
instance Class Int where
data Associated Int b = Foo deriving Show
getShow = ShowDict
main = print $ showAssociated Foo
This is somewhat similar to the function copying you propose, but advantages are:
- Avoids repetition (of `Context`'s method signatures)
- Having `Show Baz` in context is somewhat more powerful than just having a function for showing a `Baz`, since it allows you to call (library) functions which require `Show Baz`, or use implied instances like `Show [Baz]`:
showAssociateds :: forall a b. Class a => [Associated a b] -> String
showAssociateds as =
case getShow :: ShowDict (Associated a b) of
ShowDict ->
show as
The main disadvantage is that using getShow
always requires an explicit type signature (functions like getShowFor
can mitigate this).
这篇关于如何限制关联的数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!