
Hi Martin, I will present a few possibilities so that you can choose one that's available to you. Let's first think about what the code is doing. It is adding an item to the ItemDB. However you are operating on the granulity of a System so you want a function of type:itmAdd :: Item -> System -> System. If we had it then we could write: sysAddItem lbl vol cap pos t = do sys <- get id <- sysNextId :: State SystemId modify $ itmAdd (Itm id lbl vol cap pos t) return id That looks nicer. I'm guessing you don't have itmAdd at hand. One way would be to write it ourselves using itmAdd': itmAdd :: Item -> System -> System itmAdd item s = s{sysItems=execState (itmAdd' item) (sysItems s)} So this solution only hides the ugliness. The reason why it appears is because itmAdd' has a too specific type - an unnecessary State. What it essentially does is it adds an Item to ItemDB, so: itmAdd'' :: Item -> ItemDB -> ItemDB, then the function would look better. I myself would first write itmAdd'' (instead of itmAdd') and then if I really needed itmAdd' in multiple places I would write itmAdd item s = s{sysItems=itmAdd'' item $ sysItems s} itmAdd' item = modify $ itmAdd'' item The code here still may look nicer, but only slightly. My message here is that it is beneficial to think first about what are the most general types that you need and then perhaps splitting them into a combination of other general types. Here the root cause of the ugliness is that you too an unnecessarily specific type of itemAdd'. Best regards, Grzegorz On 16.10.2015 22:28, martin wrote:
Hello all,
I found myself writing this piece of code:
-- | Create and add a new 'Item' to the system sysAddItem :: ItmLabel -> ItmVolume -> ItmCapacity -> Position -> Instant -> State System ItmId
sysAddItem lbl vol cap pos t = do sys <- get id <- sysNextId :: State System Id
itms' <- return $ execState (itmAdd' (Itm id lbl vol cap pos t)) (sysItems sys) --**
modify (\sys -> sys{sysItems=itms'}) return id
In the lonely line ** in the middle I use
itmAdd' :: Item -> State ItemDb (),
where the ItemDb is part of the 'System' and can be extracted via sysItems. I believe this code is correct, but I don't like it.
The expression to the right of <- must have the type
State System ItemDb
But ItemAdd' has the type
Item -> State ItemDb ()
So I need to transform
(Item -> State ItemDb ()) to (State System ItemDb).
There is no question that I have to pass the Item, but the transformation of the States is quite noisy. Is there a better way to make this transformation, given a function System->ItemDb (i.e. sysItems)? _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners