首页 文章

Haskell类型类和重复行为

提问于
浏览
3

我是Haskell的新手并尝试在程序中概括一些行为,以减少代码量并整体提供更简单的解决方案 .

假设我有这种类型代表邮政编码,例如'ABC 123':

type PostCode = ((Char, Char, Char), (Int, Int, Int))

并且 PostCode 的行为应该是循环的;即 AAA 000 来自 AAA 001 ; 'A'至'Z'对于 Char 应该是说唱回合,对于 Int 应为0-9 .

因此我引渡了这个类型:

class Cyclic a where
    next :: a -> a

这很简单 .

所以我每个人都有 instance

-- import Data.Char
instance Cyclic Char where
    next c = chr n
      where nxt = (ord c) + 1
            min  = 65
            max  = 90
            n    = if (nxt > max) then min else nxt

instance Cyclic Int where
    next i = n
      where nxt = i + 1
            min  = 0
            max  = 9
            n    = if (nxt > max) then min else nxt

这给我留下了几个明显的要点:

  • minmax 的概念是重复的

  • next为 Int 重新实现时,唯一真正的区别是它的最小值和最大值,以及类型

如何正确抽象这种行为?有没有办法让 IntChar 的循环行为没有两个不同的实现?我可以使用其他什么Haskell功能?

1 回答

  • 4

    您可以在类型类中为 next 提供默认实现,如下所示:

    import Data.Char (chr)
    
    class (Ord a, Enum a) => Cyclic a where
        min', max' :: a
        next :: a -> a
        next a = if max' < a' then min' else  a'
            where a' = succ a
    
    instance Cyclic Char where
        min' = chr 65
        max' = chr 90
    
    instance Cyclic Int where
        min' = 0
        max' = 9
    

    或者,您可以使用辅助函数在闭包中实现 next ,如下所示:

    class Cyclic a where
        next :: a -> a
    
    -- a helper function to implement next within a closure
    cycl :: (Ord a, Enum a) => a -> a -> (a -> a)
    cycl min' max' a = if max' < a' then min' else a'
        where a' = succ a
    
    instance Cyclic Char where
        next = cycl (chr 65) (chr 90)
    
    instance Cyclic Int where
        next = cycl 0 9
    

相关问题