haskell - Modify Hashtables in the ST Monad -


so, looking mutable hashtables (for speed reasons), , updated answer don stewart led me try out hashtables.

being bit inexperienced in st monad, expanded given example to:

{-# language overloadedstrings #-} {-# language scopedtypevariables #-} {-# language flexiblecontexts #-}  import qualified data.hashtable.st.cuckoo c import qualified data.hashtable.class h import control.monad.st.safe import data.text  type hashtable s k v = c.hashtable s k v  foo :: st s (hashtable s text int) foo =   ht <- h.newsized 1   h.insert ht "abc" 1   h.insert ht "dea" 3   return ht  add1 :: hashtable s text int -> st s (hashtable s text int) add1 ht =   h.insert ht "abc" 2   h.insert ht "dea" 4   return ht  main =   let x = runst $ h.tolist =<< foo   print x   let y = runst $ h.tolist =<< add1 =<< foo   print y 

from (limited) understanding allows operate on data structures in mutable way, 'freeze them' , present result in such way can escaped from, through runst - , can use let bindings, , not <-.

however, failing see how operate on hashtable without converting to/from lists. following code not compile:

   -- not compile    let z = runst foo    let w = runst $ add1 z    print w 

it gives following error (among others): hashtable.hs:31:19:

couldn't match type `a' `c.hashtable s text int'   `a' rigid type variable bound       inferred type of z :: @ hashtable01.hs:31:7 expected type: st s   actual type: st s (hashtable s text int) in second argument of `($)', namely `foo' in expression: runst $ foo in equation `z': z = runst $ foo 

this due s constrain in type, , guess it's there precisely reason. if later use z not have same value, since add1 operated in place, , not pure. correct?

but then, st monad in particular case useful situation where:

  • you give fixed input
  • you calculate new value based on it, using mutable data structures
  • you freeze result, making imutable again.

any further change requires tolist/fromlist efectively copies values , keeps original imutable. writing this, i'm thinking - duh, definition of pure function, used everywhere in haskell, , use case st monad (have reached st enlightenment?)

so, guess real question in case is: isn't tolist/fromlist operation expensive (2xo(n)), , couldn't there way operate on copy without tolist/fromlist pair of functions. or overcomplicating, , should use io version of hashtables?

you correct can't operate on hashtable once leaves st monad. answer not tolist/fromlist marshaling, instead have single runst scopes on everything need mutating table.

i.e. louis wrote in comments: "pull else st monad until have function uses hash table internal implementation detail , doesn't expose rest of code".


Comments