2013-08-29 47 views
1

我遇到了一个问题,我认为我可能在Haskell知识上存在差距。我试图实现一个名为after的函数,该函数将被赋予一个项目或一个列表,并显示它后面的内容。在Haskell中重载通用函数

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. 

这样的错误,是我的做法根本性的缺陷?怎样才能实现泛型函数重载,带或不带类型类?

+0

我不知道这是否可能,我对这方面的解决方案非常感兴趣。只是一个想法:我想你可以只写afterList,并确保在函数的开头将所有单个项目转换为单例列表。 – vroomfondel

回答

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 

请注意,尽管您的实现看起来不起作用。但他们现在进行类型检查。

+0

这起作用。为了使上面的代码工作,我将子行中的行从'sub _ 0 = []'改为'sub x 0 = x'。没有意识到类在他们的定义中使用了这样的通用术语。 –