I've come across a problem where I think I may have a gap in my knowledge of Haskell. I'm trying to implement a function called after
, that will either be given an item or a list, and display what comes after it.
after "sample" 'a'
should return "mple".
after "sample" "am"
should return "ple".
I know how to define both of these functions as after
and afterList
, but I am trying to make a generic function to handle both
after :: (Eq a) => [a] -> a
and
after :: (Eq a) => [a] -> [a]
Is such a function possible? My attempt at this was:
{-# 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
But that returns an error of
test.hs:13:28:
Unexpected type `[a]' where type variable expected
In the declaration of `Continuous [a] a'
Failed, modules loaded: none.
So, is my approach fundamentally flawed? How can one achieve generic function overloading, with or without typeclasses?
Your approach is quite right, but you need to write it out properly.
{-# 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
Note that your implementations don't seem to work, though. But they do type-check now.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.