Haskell: Recursion with a polymorphic equality function - haskell

Ok so we have not learned polymorphic functions yet, but we still have to write this code.
Given:
nameEQ (a,_) (b,_) = a == b
numberEQ (_,a) (_,b) = a == b
intEQ a b = a == b
member :: (a -> a -> Bool) -> a -> [a] -> Bool
I added:
member eq x ys | length ys < 1 = False
| head(ys) == x = True
| otherwise = member(x,tail(ys))
but i get errors about not being the correct type as well as some other stuff. We have to see if an element exists in from some type. So we have those 2 types above. Some examples given:
phoneDB = [("Jenny","867-5309"), ("Alice","555-1212"), ("Bob","621-6613")]
> member nameEQ ("Alice","") phoneDB
True
> member nameEQ ("Jenny","") phoneDB
True
> member nameEQ ("Erica","") phoneDB
False
> member numberEQ ("","867-5309") phoneDB
True
> member numberEQ ("","111-2222") phoneDB
False
> member intEQ 4 [1,2,3,4]
True
> member intEQ 4 [1,2,3,5]
False
not exactly sure what i need to do here. Any help or documentation on this would be great. Thanks!

Various things (I'm not going to write out the full answer as this is homework):
length ys < 1 can be more simply expressed as null ys
You don't need brackets around function arguments. head(ys) is more commonly written as head ys
You can, if you want, turn the top case and the other two into pattern matches rather than guards. member eq x [] = ... will match the empty case, member eq x (y:ys) = ... will match the non-empty case.
You are using == for comparison. But you're meant to use the eq function you're given instead.
You are bracketing the arguments to member as if this was Java or similar. In Haskell, arguments are separated by spaces, so member(x,(tail(ys)) should be member x (tail ys).

Those errors you gloss over "about not being the correct type as well as some other stuff" are important. They tell you what's wrong.
For example, the first time I threw your code into ghc I got:
Couldn't match expected type `a -> a -> Bool'
against inferred type `(a1, [a1])'
In the first argument of `member', namely `(x, tail (ys))'
In the expression: member (x, tail (ys))
In the definition of `member':
member eq x ys
| length ys < 1 = False
| head (ys) == x = True
| otherwise = member (x, tail (ys))
Well, when I look at it that's straightforward - you've typed
member(x,tail(ys))
When you clearly meant:
member x (tail ys)
Commas mean something in Haskell you didn't intend there.
Once I made that change it complained again that you'd left off the eq argument to member.
The error after that is tougher if you haven't learned about Haskell typeclasses yet, but suffice it to say that you need to use the passed-in eq function for comparing, not ==.

Since the parameters a in member :: (a -> a -> Bool) -> a -> [a] -> Bool
don't derive Eq, you can't use == to compare them,
but instead have to use the given function eq.
Therefore your code might look like this:
member :: (a -> a -> Bool) -> a -> [a] -> Bool
member eq x ys
| length ys < 1 = False
| eq x (head ys) = True
| otherwise = member eq x (tail ys)
Only problem with this is, that length still requires to evaluate the entire List,
so you could reach a a better performance writing:
member' :: (a -> a -> Bool) -> a -> [a] -> Bool
member' eq x (y:ys)
| eq x y = True
| otherwise = member' eq x ys
member' _ _ [] = False
With the use of any you can simplify it even more:
member'' :: (a -> a -> Bool) -> a -> [a] -> Bool
member'' f a = any (f a)

Related

Recursive definition of the (!!)-function

So I tried to build the (!!) function as already defined in GHC.List recursively.
I want to extract the n-th element of a list and return that.
Here's what I got first:
taken0 :: [β] -> Int -> β -- but not recursive
βs `taken0` 0 = head βs
βs `taken0` n = last (take (n+1) βs)
This worked, but it wasn't recursive...
then I tried the following:
taken :: [γ] -> Int -> γ -- doesn't compile
taken γs 0 = head γs
taken γs 1 = head (tail γs)
taken γs n = head ( tail (takenth γs (n-1)) )
After some fixing I ended up with this:
taken :: [γ] -> Int -> [γ] -- works, but returns a list
taken γs 0 = γs
taken γs 1 = tail γs
taken γs n = tail (taken γs (n-1))
Which does indeed compile but is ugly to handle, it returns a list whoose first element is that one "entered" by n.
*Main> head ([0,1,2,3,4,5,6,7,8,9] `taken` 0) returns 0
*Main> head ([0,1,2,3,4,5,6,7,8,9] `taken` 1) returns 1
*Main> head ([0,1,2,3,4,5,6,7,8,9] `taken` 2) returns 2
etc.
Always returns the right (n-th element)
but I had to insert head before.
What I want is a function, which, although recursive, returns a single element instead of a list...
Is there a way to accomplish this without writing another function or using head everytime ?
like:
*Main> taken2 [5,8,6,0,2,5,7] 3 returns 0
thanks in advance !
taken :: [γ] -> Int -> [γ] -- works, but returns a list
taken γs 0 = γs
taken γs 1 = tail γs
taken γs n = tail (taken γs (n-1))
This is very close. There are three problems:
You have too many cases. You only need these two:
taken ys 0 = ...
taken ys n = ...
You want to return an element of the list, not a list. In particular, the first rule needs to return the first element of the list. One way to do this is with head:
taken ys 0 = head ys
Now we need to fix the second rule. We want to write this recursively, so we want to do something like this:
taken ys n = taken ?? ??
What do we put in place of the ??s? Well, we know that n is at least 1. And if we get down to 0, we can use the first rule to return the result. This suggests that the second parameter should be (n-1) as you already have tried.
We also know that the first element of ys isn't the right one to use, so we want to throw it away. To do this, we can use tail ys. Putting this all together we get
taken ys n = taken (tail ys) (n-1)
So it seems that the main mistake here is you were applying tail in the wrong place.
Notes
This solution isn't robust. It will cause an infinite recursion if you call it with a negative index. Handling for this case is left as an exercise for the reader.
You can use pattern matching instead of head and tail. For example, the first case can be written as
taken (y:_) 0 = y
I leave implementing the second case with pattern matching as an exercise for the reader.
Writing a recursive function on lists, you should almost always start by mirroring the recursive definition of the list type itself: a case for empty lists, and a case for a cons pair:
taken :: [γ] -> Int -> γ
taken [] n = _
taken (γ:γs) n = _
Note, the above syntax with underscore placeholders is actual Haskell syntax (for recent enough GHC), which will cause the compiler to print out errors like this asking you to fill in the blanks, and telling you about the pieces you have available to fill them in:
foo.hs:2:14: error:
• Found hole: _ :: γ
Where: ‘γ’ is a rigid type variable bound by
the type signature for:
taken :: forall γ. [γ] -> Int -> γ
at foo.hs:1:1-24
• In the expression: _
In an equation for ‘taken’: taken [] n = _
• Relevant bindings include
n :: Int (bound at foo.hs:2:10)
taken :: [γ] -> Int -> γ (bound at foo.hs:2:1)
|
2 | taken [] n = _
| ^
foo.hs:3:18: error:
• Found hole: _ :: γ
Where: ‘γ’ is a rigid type variable bound by
the type signature for:
taken :: forall γ. [γ] -> Int -> γ
at foo.hs:1:1-24
• In the expression: _
In an equation for ‘taken’: taken (γ : γs) n = _
• Relevant bindings include
n :: Int (bound at foo.hs:3:14)
γs :: [γ] (bound at foo.hs:3:10)
γ :: γ (bound at foo.hs:3:8)
taken :: [γ] -> Int -> γ (bound at foo.hs:2:1)
|
3 | taken (γ:γs) n = _
|
So the first hole we need to fill in is of type γ. However the only things we have available are the Int n, and making a recursive call to taken. Since the list is empty, recursing isn't going to help us; it'll just end up back at the same case we're in. And thinking about what our function is supposed to do, we can't get the nth element of an empty list no matter what n is. So we'll need to just call error here.
taken :: [γ] -> Int -> γ
taken [] n = error "Index out of range"
taken (γ:γs) n = _
The second hole is also of type γ, and GHC tells us:
• Relevant bindings include
n :: Int (bound at foo.hs:3:14)
γs :: [γ] (bound at foo.hs:3:10)
γ :: γ (bound at foo.hs:3:8)
taken :: [γ] -> Int -> γ (bound at foo.hs:2:1)
So we can obviously just use γ to appease the type checker, but logically which value we return should depend on n. If we're taking the 0th element of this list, well we've already got the head element decomposed as value γ due to our pattern match, so that'll be correct in that case. Lets try:
taken :: [γ] -> Int -> γ
taken [] n = error "Index out of range"
taken (γ:γs) n
| n == 0 = γ
| otherwise = _
Which gives us:
foo.hs:5:17: error:
• Found hole: _ :: γ
Where: ‘γ’ is a rigid type variable bound by
the type signature for:
taken :: forall γ. [γ] -> Int -> γ
at foo.hs:1:1-24
• In the expression: _
In an equation for ‘taken’:
taken (γ : γs) n
| n == 0 = γ
| otherwise = _
• Relevant bindings include
n :: Int (bound at foo.hs:3:14)
γs :: [γ] (bound at foo.hs:3:10)
γ :: γ (bound at foo.hs:3:8)
taken :: [γ] -> Int -> γ (bound at foo.hs:2:1)
|
5 | | otherwise = _
|
Same type of hole, same relevant bindings available. But we know that γ isn't the right answer, since we've already handled the case when it is. The answer we do want to return should be somewhere in γs, and we know we want to write this function recursively, so the obvious thing to do is insert a recursive call:
taken :: [γ] -> Int -> γ
taken [] n = error "Index out of range"
taken (γ:γs) n
| n == 0 = γ
| otherwise = taken γs _
foo.hs:5:26: error:
• Found hole: _ :: Int
• In the second argument of ‘taken’, namely ‘_’
In the expression: taken γs _
In an equation for ‘taken’:
taken (γ : γs) n
| n == 0 = γ
| otherwise = taken γs _
• Relevant bindings include
n :: Int (bound at foo.hs:3:14)
γs :: [γ] (bound at foo.hs:3:10)
γ :: γ (bound at foo.hs:3:8)
taken :: [γ] -> Int -> γ (bound at foo.hs:2:1)
|
5 | | otherwise = taken γs _
|
Now we're getting somewhere. The remaining hole is of type Int, and we have n :: Int available. Plugging that straight in is tempting, but doesn't make sense if we stop to think about what we're doing. Taking the nth element of the list (γ:γs) (which is the result we're supposed to be returning) when n \= 0 should be the same as taking the (n - 1)th element of γs, so:
taken :: [γ] -> Int -> γ
taken [] n = error "Index out of range"
taken (γ:γs) n
| n == 0 = γ
| otherwise = taken γs (n - 1)
No more holes! And this actually works. The only problem is that we don't handle negative values of n. It turns out that's actually sortof okay; for finite lists we eventually run off the end and hit the error "Index out of range" case, which is accurate. But it would be nicer to fail before iterating the whole list. So:
taken :: [γ] -> Int -> γ
taken [] n = error "Index out of range"
taken (γ:γs) n
| n == 0 = γ
| n < 0 = error "Negative index"
| otherwise = taken γs (n - 1)
I highly recommend this "hole driven development" style (whether you use actual hole syntax and get GHC to typecheck them or just do it yourself as you write the code). Let the structure of the types you're using guide the "shape" of the function you're writing (e.g. when writing a function on lists, use a case for [] and a case for (x:xs)), and then fill in the holes one at a time. Sometimes you'l need a different structure than this guides you towards, but very often not, and even when you do having started this approach and found out what the problems are gives you much better information for guessing the right structure.
Yes, a straightforward one is:
nth0 :: [a] -> Int -> a
nth0 (x:xs) i | i >= 1 = nth0 xs (i-1)
| i < 0 = error "Index less than zero"
| otherwise = x
nth0 [] i = error "Index too large"
So the recursive part is the nth0 xs (i-1). Here we thus perform recursion on the tail of the list xs, and with a decremented index i-1.
The base case is the otherwise (which fires in case i == 0), in which case we return the head of the list x.
The remaining cases cover the fact that the index could be negative, or that the index is greater than, or equal to the length of the list.

Recursively dropping elements from list in Haskell

Right now I'm working on a problem in Haskell in which I'm trying to check a list for a particular pair of values and return True/False depending on whether they are present in said list. The question goes as follows:
Define a function called after which takes a list of integers and two integers as parameters. after numbers num1 num2 should return true if num1 occurs in the list and num2 occurs after num1. If not it must return false.
My plan is to check the head of the list for num1 and drop it, then recursively go through until I 'hit' it. Then, I'll take the head of the tail and check that against num2 until I hit or reach the end of the list.
I've gotten stuck pretty early, as this is what I have so far:
after :: [Int] -> Int -> Int -> Bool
after x y z
| y /= head x = after (drop 1 x) y z
However when I try to run something such as after [1,4,2,6,5] 4 5 I get a format error. I'm really not sure how to properly word the line such that haskell will understand what I'm telling it to do.
Any help is greatly appreciated! Thanks :)
Edit 1: This is the error in question:
Program error: pattern match failure: after [3,Num_fromInt instNum_v30 4] 3 (Num_fromInt instNum_v30 2)
Try something like this:
after :: [Int] -> Int -> Int -> Bool
after (n:ns) a b | n == a = ns `elem` b
| otherwise = after ns a b
after _ _ _ = False
Basically, the function steps through the list, element by element. If at any point it encounters a (the first number), then it checks to see if b is in the remainder of the list. If it is, it returns True, otherwise it returns False. Also, if it hits the end of the list without ever seeing a, it returns False.
after :: Eq a => [a] -> a -> a -> Bool
after ns a b =
case dropWhile (/= a) ns of
[] -> False
_:xs -> b `elem` xs
http://hackage.haskell.org/package/base-4.8.2.0/docs/src/GHC.List.html#dropWhile
after xs p1 p2 = [p1, p2] `isSubsequenceOf` xs
So how can we define that? Fill in the blanks below!
isSubsequenceOf :: Eq a => [a] -> [a] -> Bool
[] `isSubsequenceOf` _ = ?
(_ : _) `isSubsequenceOf` [] = ?
xss#(x : xs) `isSubsequenceOf` (y:ys)
| x == y = ?
| otherwise = ?
after :: [Int] -> Int -> Int -> Bool
Prelude> let after xs a b = elem b . tail $ dropWhile (/=a) xs
Examples:
Prelude> after [1,2,3,4,3] 88 7
*** Exception: Prelude.tail: empty list
It raises an exception because of tail. It's easy to write tail' such that it won't raise that exception. Otherwise it works pretty well.
Prelude> after [1,2,3,4,3] 2 7
False
Prelude> after [1,2,3,4,3] 2 4
True

Haskell Continuation passing style index of element in list

There's a series of examples I'm trying to do to practice Haskell. I'm currently learning about continuation passing, but I'm a bit confused as to how to implement a function like find index of element in list that works like this:
index 3 [1,2,3] id = 2
Examples like factorial made sense since there wasn't really any processing of the data other than multiplication, but in the case of the index function, I need to compare the element I'm looking at with the element I'm looking for, and I just can't seem to figure out how to do that with the function parameter.
Any help would be great.
first let me show you a possible implementation:
index :: Eq a => a -> [a] -> (Int -> Int) -> Int
index _ [] _ = error "not found"
index x (x':xs) cont
| x == x' = cont 0
| otherwise = index x xs (\ind -> cont $ ind + 1)
if you prefer point-free style:
index :: Eq a => a -> [a] -> (Int -> Int) -> Int
index _ [] _ = error "not found"
index x (x':xs) cont
| x == x' = cont 0
| otherwise = index x xs (cont . (+1))
how it works
The trick is to use the continuations to count up the indices - those continuations will get the index to the right and just increment it.
As you see this will cause an error if it cannot find the element.
examples:
λ> index 1 [1,2,3] id
0
λ> index 2 [1,2,3] id
1
λ> index 3 [1,2,3] id
2
λ> index 4 [1,2,3] id
*** Exception: not found
how I figured it out
A good way to figure out stuff like this is by first writing down the recursive call with the continuation:
useCont a (x:xs) cont = useCont a xs (\valFromXs -> cont $ ??)
And now you have to think about what you want valFromXs to be (as a type and as a value) - but remember your typical start (as here) will be to make the first continuation id, so the type can only be Int -> Int. So it should be clear that we are talking about of index-transformation here. As useCont will only know about the tail xs in the next call it seems natural to see this index as relative to xs and from here the rest should follow rather quickly.
IMO this is just another instance of
Let the types guide you Luke
;)
remarks
I don't think that this is a typical use of continuations in Haskell.
For once you can use an accumulator argument for this as well (which is conceptional simpler):
index :: Eq a => a -> [a] -> Int -> Int
index _ [] _ = error "not found"
index x (x':xs) ind
| x == x' = ind
| otherwise = index x xs (ind+1)
or (see List.elemIndex) you can use Haskells laziness/list-comprehensions to make it look even nicer:
index :: Eq a => a -> [a] -> Int
index x xs = head [ i | (x',i) <- zip xs [0..], x'== x ]
If you have a value a then to convert it to CPS style you replace it with something like (a -> r) -> r for some unspecified r. In your case, the base function is index :: Eq a => a -> [a] -> Maybe Int and so the CPS form is
index :: Eq a => a -> [a] -> (Maybe Int -> r) -> r
or even
index :: Eq a => a -> [a] -> (Int -> r) -> r -> r
Let's implement the latter.
index x as success failure =
Notably, there are two continuations, one for the successful result and one for a failing one. We'll apply them as necessary and induct on the structure of the list just like usual. First, clearly, if the as list is empty then this is a failure
case as of
[] -> failure
(a:as') -> ...
In the success case, we're, as normal, interested in whether x == a. When it is true we pass the success continuation the index 0, since, after all, we found a match at the 0th index of our input list.
case as of
...
(a:as') | x == a -> success 0
| otherwise -> ...
So what happens when we don't yet have a match? If we were to pass the success continuation in unchanged then it would, assuming a match is found, eventually be called with 0 as an argument. This loses information about the fact that we've attempted to call it once already, though. We can rectify that by modifying the continuation
case as of
...
(a:as') ...
| otherwise -> index x as' (fun idx -> success (idx + 1)) failure
Another way to think about it is that we have the collect "post" actions in the continuation since ultimately the result of the computation will pass through that code
-- looking for the value 5, we begin by recursing
1 :
2 :
3 :
4 :
5 : _ -- match at index 0; push it through the continuation
0 -- lines from here down live in the continuation
+1
+1
+1
+1
This might be even more clear if we write the recursive branch in pointfree style
| otherwise -> index x as' (success . (+1)) failure
which shows how we're modifying the continuation to include one more increment for each recursive call. All together the code is
index :: Eq a => a -> [a] -> (Int -> r) -> r -> r
index x as success failure
case as of
[] -> failure
(a:as') | x == a -> success 0
| otherwise -> index x as' (success . (+1)) failure

Type error in explicitly typed binding in Haskell

I'm a having a type error on my Haskell Code. termEnVoc is expected to return True if the Term given is part of the Vocabulario (vocabulary), I'm not completely sure if it works but anyway I can't understand why do I get a type error.
Here it's the code:
type Cte = Simbolo
type Funcion = (Simbolo,Aridad)
type Predicado = (Simbolo, Aridad)
type Vocabulario = ([Cte], [Funcion], [Predicado])
data Term = C Simbolo | L Var | F Simbolo [Term]
deriving (Show, Eq)
termEnVoc :: Term -> Vocabulario -> Bool --This is line 38, the one with the error
termEnVoc = \t -> \(cs,fs,ps)-> (or(map (\x ->(x==t))cs) || or(map (\x ->(x==t))f) || or(map (\x ->(x==t))p));
And here the error:
ERROR file:.\tarea3.hs:38 - Type error in explicitly typed binding
*** Term : termEnVoc
*** Type : [Char] -> ([[Char]],[([Char],Int)],[([Char],Int)]) -> Bool
*** Does not match : Term -> Vocabulario -> Bool
As chi suggests, the main problem appears to be that you are trying to compare Terms with values of other types. It's hard to see just what you're trying to do (specifically, what different types are supposed to represent), but here's the general way you probably want to structure the function definition:
termEnVoc (C simbolo) (cs, fs, ps) = cte `elem` cs
termEnVoc (F simbolo termList) (cs, fs, ps) = head $ filter ((== f) . fst) fs
termEnVoc (L var) (cs, fs, ps) = head $ filter ((== var) . fst) ps
As I indicated, some (or even most) of the details may be wrong, but this should give you a sense of how to structure the definition. The code above makes use of the following:
(== x) = (\y -> y == x)
You can actually do this with operators in general:
(/ 3) = (\x -> x/3)
and
(3 /) = (\x -> 3/x)
The only one that's wonky is subtraction, and I always have to look up the rules for that.
elem a as = or $ map (== a) as
a `elem` b = elem a b
filter p [] = []
filter p (x:xs)
| p x = x : filter p xs
| otherwise = filter p xs
Note that the real definitions of the above are likely different, for efficiency reasons.
I finally decided that the problem was as dfeuer said that I was comparing terms with values of other types.
I end up with this method:
esTerm :: Vocabulario -> Term -> Bool
esTerm = \(c,f,p)-> \t -> case t of {
C x -> elem x c;
L x -> True;
F n ts -> case (lookup n f) of {
Nothing -> False;
Just x -> x==(length ts)&& and(map (esTerm (c,f,p)) ts);
}
}
Thanks for the help, it was really useful for fixing other mistakes I was making on my project.

Defining a Boolean function on Haskell that determines if an element occurs once in a list

So I'm trying to define a function in Haskell that if given an integer and a list of integers will give a 'true' or 'false' whether the integer occurs only once or not.
So far I've got:
let once :: Eq a => a -> [a] -> Bool; once x l =
But I haven't finished writing the code yet. I'm very new to Haskell as you may be able to tell.
Start off by using pattern matching:
once x [] =
once x (y:ys) =
This won't give you a good program immediately, but it will lead you in the right direction.
Here's a solution that doesn't use pattern matching explicitly. Instead, it keeps track of a Bool which represents if a occurance has already been found.
As others have pointed out, this is probably a homework problem, so I've intentionally left the then and else branches blank. I encourage user3482534 to experiment with this code and fill them in themselves.
once :: Eq a => a -> [a] -> Bool
once a = foldr f False
where f x b = if x == a then ??? else ???
Edit: The naive implementation I was originally thinking of was:
once :: Eq a => a -> [a] -> Bool
once a = foldr f False
where f x b = if x == a then b /= True else b
but this is incorrect as,
λ. once 'x' "xxx"
True
which should, of course, be False as 'x' occurs more than exactly once.
However, to show that it is possible to write once using a fold, here's a revised version that uses a custom monoid to keep track of how many times the element has occured:
import Data.List
import Data.Foldable
import Data.Monoid
data Occur = Zero | Once | Many
deriving Eq
instance Monoid Occur where
mempty = Zero
Zero `mappend` x = x
x `mappend` Zero = x
_ `mappend` _ = Many
once :: Eq a => a -> [a] -> Bool
once a = (==) Once . foldMap f
where f x = if x == a then Once else Zero
main = do
let xss = inits "xxxxx"
print $ map (once 'x') xss
which prints
[False,True,False,False,False]
as expected.
The structure of once is similar, but not identical, to the original.
I'll answer this as if it were a homework question since it looks like one.
Read about pattern matching in function declarations, especially when they give an example of processing a list. You'll use tools from Data.List later, but probably your professor is teaching about pattern matching.
Think about a function that maps values to a 1 or 0 depending on whethere there is a match ...
match :: a -> [a] -> [Int]
match x xs = map -- fill in the thing here such that
-- match 3 [1,2,3,4,5] == [0,0,1,0,0]
Note that there is the sum function that takes a list of numbers and returns the sum of the numbers in the list. So to count the matches a function can take the match function and return the counts.
countN :: a -> [a] -> Int
countN x xs = ? $ match x xs
And finally a function that exploits the countN function to check for a count of only 1. (==1).
Hope you can figure out the rest ...
You can filter the list and then check the length of the resulting list. If length == 1, you have only one occurrence of the given Integer:
once :: Eq a => a -> [a] -> Bool
once x = (== 1) . length . filter (== x)
For counting generally, with import Data.List (foldl'), pointfree
count pred = foldl' (\ n x -> if pred x then n + 1 else n) 0
applicable like
count (< 10) [1 .. 10] == 9
count (== 'l') "Hello" == 2
gives
once pred xs = count pred xs == 1
Efficient O(n) short-circuit predicated form, testing whether the predicate is satisfied exactly once:
once :: (a -> Bool) -> [a] -> Bool
once pred list = one list 0
where
one [] 1 = True
one [] _ = False
one _ 2 = False
one (x : xs) n | pred x = one xs (n + 1)
| otherwise = one xs n
Or, using any:
none pred = not . any pred
once :: (a -> Bool) -> [a] -> Bool
once _ [] = False
once pred (x : xs) | pred x = none pred xs
| otherwise = one pred xs
gives
elemOnce y = once (== y)
which
elemOnce 47 [1,1,2] == False
elemOnce 2 [1,1,2] == True
elemOnce 81 [81,81,2] == False

Resources