[Haskell-beginners] RDBMS like references?

Theodore Lief Gannon tanuki at gmail.com
Tue Jun 28 22:10:22 UTC 2016


Another possibility would be to keep your definition for Location, but
switch to:

data Item a = Item a
type ItemDB = Map Item Location

...and use a recursive lookup to find the location of an item contained
within another. This is quite a bit simpler, but whether it's preferable
probably depends on whether your more common lookup is "where is item x?"
vs. "what's at location y?"
On Jun 28, 2016 2:26 PM, "Theodore Lief Gannon" <tanuki at gmail.com> wrote:

> 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/b353cc5e/attachment.html>


More information about the Beginners mailing list