Haskell:类型类和实例

时间:2015-11-13 11:36:22

标签: list haskell set instance typeclass

对于类型类并从中创建实例,我遇到了一些可能很简单的问题。 我正在尝试为Haskell List和Set函数中的某些函数创建一个类型类,例如“size”,“null”和“filter”。 我已经使用“

”获得了“size”和“null”的工作
 module Main where

  import qualified Data.List as DL
  import qualified Data.Set as DS

  class Interface a where
      null' :: [a] -> Bool
      size' :: a -> Int

  instance Interface [a] where
      null' xs = DL.null xs
      size' xs = DL.length xs

  instance Interface (DS.Set a) where
      null' x = DS.null x
      size' x = DS.size x

这个功能在我测试时起作用。现在我试着实现了 过滤功能

class Interface a where
    null' :: [a] -> Bool
    size' :: a -> Int
    filter' :: (a-> Bool) -> a -> a

instance Interface [a] where
    null' xs = DL.null xs
    size' xs = DL.length xs
    filter' f xs = DL.filter f xs

我现在遇到的问题如下:

ue4.hs:17:30:
    Couldn't match type ‘a’ with ‘[a]’
      ‘a’ is a rigid type variable bound by
          the instance declaration at ue4.hs:14:10
    Expected type: a -> Bool
      Actual type: [a] -> Bool
    Relevant bindings include
      xs :: [a] (bound at ue4.hs:17:15)
      f :: [a] -> Bool (bound at ue4.hs:17:13)
      filter' :: ([a] -> Bool) -> [a] -> [a] (bound at ue4.hs:17:5)
    In the first argument of ‘filter’, namely ‘f’
    In the expression: filter f xs

据我所知,问题在功能范围内。它需要获得一个正常值,以便遍历地图并使用所有值评估函数,以将它们放入结果列表中,该结果列表将由过滤器返回。但是实例声明中的[a]将所有内容都作为列表读取,它不应该。

如果我把

        filter' :: (a-> Bool) -> [a] -> [a]

进入该类,我认为我可以使用列表过滤器,但是后来我遇到了Set过滤器的问题,并且Typeclass的意义已经丢失。

有没有人知道如何处理或如何解决这个问题?我必须采取什么作为类定义?

1 个答案:

答案 0 :(得分:1)

  

我已经通过

使用“size”和“null”工作了

真的?这看起来像是一个错误。 null'的定义非常难以理解。对于列表,您有:

null' :: [[a]] -> Bool

对于Set,您有:

null' :: [Set a] -> Bool

我很肯定这不是你想要的。

也许这样的事情更合适:

module Main where
import qualified Data.List as DL
import qualified Data.Set as DS

class Interface a where
  null' :: a x -> Bool
  size' :: a x -> Int
  filter' :: (x -> Bool) -> a x -> a x

instance Interface [] where
  null' = DL.null
  size' = DL.length
  filter' = DL.filter

instance Interface DS.Set where
  null' = DS.null
  size' = DS.size
  filter' = DS.filter

请注意,我已将您的界面更改为适用于更高级别的类型,因此[a]本身不是[]作为您班级的实例,而是您班级的实例。这可能不是您想要的,但它确实允许您实施map(但唉,不是Set)。