如何限制关联的数据? [英] How to put constraints on the associated data?

查看:107
本文介绍了如何限制关联的数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  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

  • 避免重复(Context的方法签名)
  • >

  • 在上下文中显示Baz功能比仅显示Baz功能更强大,因为它允许您调用(库)函数,它需要显示Baz ``,或者使用隐含的实例,比如`Show [Baz]`:

    $ 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).

    这篇关于如何限制关联的数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆