[Haskell-beginners] RDBMS like references?

Theodore Lief Gannon tanuki at gmail.com
Tue Jun 28 21:26:49 UTC 2016


Sometimes relational is the way to go, but it's always worth looking for
other options. :) The idiomatic preference, I think, would be to separate
the nesting structure from the object data. The item containment graph
sounds like a RoseTree, and since location is always inherited, that can
just be a Map.

import qualified Data.Map as M
data Rose a = Rose a [Rose a] deriving (Eq, Show)
data Item a = Item a deriving (Eq, Show)
type ItemGraph a = Rose (Item a)
type ItemDB k a = M.Map k (ItemGraph a)

>>> let ex_itemdb = M.fromList [("a", Rose (Item 1) [Rose (Item 2) []])]
>>> M.lookup "a" ex_itemdb
Just (Rose (Item 1) [Rose (Item 2) []])

>>> let roseContains i (Rose x xs) = i == x || any (roseContains i) xs
>>> let isItemAt i l idb = maybe False id $ roseContains i <$> M.lookup l
idb
>>> isItemAt (Item 2) "a" ex_itemdb
True

>>> let swapLoc l1 l2 idb = let {i1 = M.lookup l1 idb; i2 = M.lookup l2
idb} in maybe (M.delete l1) (M.insert l1) i2 . maybe (M.delete l2)
(M.insert l2) i1 $ idb
>>> let moved = swapLoc "a" "b" ex_itemdb
>>> isItemAt (Item 2) "a" moved
False
>>> moved
fromList [("b",Rose (Item 1) [Rose (Item 2) []])]

There are quite a few unfinished pieces here, but hopefully it gets you
thinking in new directions!

On Tue, Jun 28, 2016 at 11:39 AM, martin <martin.drautzburg at web.de> wrote:

> Hello all,
>
> I recently tried to model "Items", where an Item can either be inside
> another Item or at a certain location. I started
> like this:
>
> data Location i l = At l
>                   | In (Item i l)
>                     deriving (Eq, Show)
>
> data Item i l     = Itm i (Location i l)
>                     deriving (Eq, Show)
>
> type ItemDb i l = [Item i l]
>
> ex_itemdb = let i1 = Itm 1 (At "a")
>                 i2 = Itm 2 (In i1)
>             in [i1, i2]
>
> Now I wanted to move Item 1 to a different location using this code:
>
> moved = fmap f ex_itemdb
>         where
>             f (Itm 1 (At "a")) = (Itm 1 (At "b"))
>             f x = x
>
> Not this does not do what I want. I get
>
> -- *Main> ex_itemdb
> -- [Itm 1 (At "a"),Itm 2 (In (Itm 1 (At "a")))]
>
> -- *Main> moved
> -- [Itm 1 (At "b"),Itm 2 (In (Itm 1 (At "a")))]
>
> While Item 1 has moved to "b" Item 2 still claims to be in an "Itm 1 (At
> "a")". I understand what's going on here and
> coming from a DB background I can see that the redundant data is the root
> of the problem.
>
> I can model this in a relational way such that the redundancy is avoided.
> But maybe there is a more haskellish/idiomatic
> way to acomplish this.
>
> Is there?
>
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/beginners/attachments/20160628/8d7c1efa/attachment.html>


More information about the Beginners mailing list