我遇到了一个问题,我认为我对Haskell的了解可能存在差距。我正在尝试实现一个名为after
的函数,它将被赋予一个项目或列表,并显示它之后的内容。
after "sample" 'a'
应该返回“mple”。
after "sample" "am"
应该返回“ple”。
我知道如何将这两个函数定义为after
和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.
那么,我的方法是否存在根本缺陷?如何在有或没有类型类的情况下实现泛型函数重载?
答案 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
请注意,您的实现似乎不起作用。但是现在他们会进行打字检查。