1

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

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

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

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

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.

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

4

1 回答 1

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

请注意,您的实现似乎不起作用。但他们现在进行类型检查。

于 2013-08-29T23:24:13.397 回答