tuples - Composition of a "List of lists" in Haskell -
i'm quite beginner here, i'm trying make composition of relations (https://en.wikipedia.org/wiki/composition_of_relations) of 2 given lists of n-lists
funcomp :: ord => [[a,a]] -> [[a,a]] -> [[a,a]] funcomp [[a,b]] [[c,d]] | b == c = [[a,d]]
for example, given:
[[1,1],[1,2],[2,2],[2,3],[3,3],[3,4],[4,4]]
and
[[1,4],[1,4],[2,3],[2,3],[3,2],[3,1],[4,1]]
should return:
[[1,4],[1,4],[1,3],[2,2],[2,1],[3,2],[3,1],[4,1]]
how 'make so'?
i've included full answer below, in hopes might find helpful. agree @erisco if you're starting out, problem might little advanced. might want start problems involve working one list/relation instead of combining two. (for example, how make relation antireflexive removing elements of form x r x? how produce set of values y such x r y fixed value x? can solve these problems both built-in haskell functions , scratch?)
anyway, start, may find helpful, standpoint of making easier read, use tuples represent relation elements, 2 example relations be:
r1 = [(1,1),(1,2),(2,2),(2,3),(3,3),(3,4),(4,4)] r2 = [(1,4),(1,4),(2,3),(2,3),(3,2),(3,1),(4,1)]
what trying construct relation consisting of composite elements created ordered pair of elements r1
, r2
. sort of thing list comprehension for:
result = [ combine x y | x <- r1, y <- r2 ]
this expression creates list of result of running combine x y
on each pair x
,y
2 relations. should combine
be? well, takes 2 elements , generates composition, might first try like:
combine (a,b) (c,d) | b == c = (a,d)
this type check, combine
partial function -- has no value pairs don't combine -- won't far. need way of writing combine
allows return combination if 1 exists return nothing otherwise.
the standard way in haskell using maybe
type:
combine (a,b) (c,d) | b == c = (a,d) | otherwise = nothing
this type checks , runs, value of result
looks like:
[just (1,4),just (1,4),nothing,nothing...]
fortunately, there's function in data.maybe
called catmaybes
need situation -- drops nothing
s , pulls just
values while dropping literal just
constructors:
> catmaybes result [(1,4),(1,4),(1,3),...]
there duplicates should removed, let's remove them using nub
data.list
:
> nub (catmaybes result) [(1,4),(1,3),(2,3),(2,2),(2,1),(3,2),(3,1),(4,1)]
which looks answer wanted, though think missed (2,3)
in example output.
the full program, generalized, looks this:
module relations import data.list import data.maybe r1 = [(1,1),(1,2),(2,2),(2,3),(3,3),(3,4),(4,4)] r2 = [(1,4),(1,4),(2,3),(2,3),(3,2),(3,1),(4,1)] combine (a,b) (c,d) | b == c = (a,d) | otherwise = nothing funccomp r1 r2 = nub $ catmaybes [ combine x y | x <- r1, y <- r2 ] result = funccomp r1 r2
if haven't already:
- get in habit of @ least considering list comprehensions in situation you're generating items 1 or more existing lists
- read documentation key modules
prelude
,data.list
, ,data.maybe
familiarize functions available there
Comments
Post a Comment