在Haskell中重载泛型函数

时间:2013-08-29 22:58:36

标签: generics haskell overloading

我遇到了一个问题,我认为我对Haskell的了解可能存在差距。我正在尝试实现一个名为after的函数,它将被赋予一个项目或列表,并显示它之后的内容。

after "sample" 'a'应该返回“mple”。

after "sample" "am"应该返回“ple”。

我知道如何将这两个函数定义为afterafterList,但我正在尝试创建一个通用函数来处理这两个函数

after :: (Eq a) => [a] -> a

after :: (Eq a) => [a] -> [a]

这样的功能可能吗?我的尝试是:

{-# LANGUAGE MultiParamTypeClasses #-}
sub :: (Eq a) => [a] -> Int -> [a]
sub [] _ = []
sub _ 0 = []
sub (x:xs) c = sub xs (c - 1)

pos :: (Eq a) => [a] -> a -> Int
pos [] _ = 0
pos (x:xs) c
  | x == c = 0
  | otherwise = 1 + pos xs c

class (Eq a) => Continuous [a] a where
  after x c = sub x (pos x c)

instance (Eq a) => Continuous [a] [a] where
  after [] _ = []
  after x c
    | take (length c) x == c = sub x ((length c)+1)
    | otherwise = after (tail x) c

但是会返回错误

test.hs:13:28:
  Unexpected type `[a]' where type variable expected
  In the declaration of `Continuous [a] a'
Failed, modules loaded: none.

那么,我的方法是否存在根本缺陷?如何在有或没有类型类的情况下实现泛型函数重载?

1 个答案:

答案 0 :(得分:3)

你的做法非常正确,但你需要正确地写出来。

{-# LANGUAGE FlexibleInstances     #-}

class Continuous list part where
  after :: list -> part -> list

instance (Eq a) => Continuous [a] a where
  after x c = sub x (pos x c)

instance (Eq a) => Continuous [a] [a] where
  after [] _ = []
  after x c
    | take (length c) x == c = sub x ((length c)+1)
    | otherwise = after (tail x) c

请注意,您的实现似乎不起作用。但是现在他们会进行打字检查。