我想实现一个数据结构,当我注册它时会给我一个“签名”,因此我可以:
可能有点模糊,但很容易用Java实现,如下所示:
class Sig {}
class DesiredDS<A> {
HashMap<Sig, A> map = new HashMap<>();
public Sig insertWithNewSig(A a) {
Sig s = new Sig();
map.put(s, a);
return s;
}
// ...
// merge will be only to merge to map and delete will be only to delete the key
}
但我抓住了我的脑袋,无法弄清楚如何在Haskell中使用参考透明度的属性。
有什么好主意吗?可能与此类似的答案是:如何在Haskell中生成可以比较相等的数据结构,而我不需要打扰决定它的值?
答案 0 :(得分:4)
最简单的可能是使用
之类的东西public class MyWebAppInitializer extends AbstractDispatcherServletInitializer {
@Override
protected WebApplicationContext createRootApplicationContext() {
return null;
}
@Override
protected WebApplicationContext createServletApplicationContext() {
XmlWebApplicationContext cxt = new XmlWebApplicationContext();
cxt.setConfigLocation("/WEB-INF/spring/dispatcher-config.xml");
return cxt;
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
你有哪些操作:
查询签名是否存在
type Signature a = IORef (Maybe a)
合并两个此类DS,同时保持正确的行为
(...&#34;正确的行为&#34;?)
删除指定的签名
live :: Signature a -> IO Bool
live ref = isJust <$> readIORef ref
创建新签名
delete :: Signature a -> IO ()
delete ref = writeIORef ref Nothing
比较平等
insertNewSignature :: a -> IO (Signature a)
insertNewSignature a = newIORef (Just a)
而且,虽然你没有要求它,但大概你实际上不仅要检查签名是否存在,而且还要从签名中恢复值,你有这个操作< / p>
(==) :: Signature a -> Signature a -> Bool
答案 1 :(得分:0)
你有很多选择!如果您希望为随机签名制作唯一性,我建议使用randomness monad来处理您的随机种子,并使用StateT
来管理您的HashMap
。像这样的东西,粗略地说:
type Sig = -- Something big enough that's an instance of `Random`
newtype DS a = DS (HashMap Sig a)
insert :: (MonadRandom m, MonadState (DS a) m) => a -> m Sig
insert a = do
ds <- get
ds' <- HM.insert <$> getRandom <*> pure a
put ds'
答案 2 :(得分:-3)
使用不安全的I / O是否在作弊?
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Lib where
import Data.Map (Map)
import qualified Data.Map as Map
import Data.Monoid
import Data.Unique (Unique)
import qualified Data.Unique as Unique
import System.IO.Unsafe
newtype Registrar a =
Registrar (Map Unique a)
deriving (Eq, Monoid)
insert :: a -> Registrar a -> (Unique, Registrar a)
insert value (Registrar amap) =
(u, Registrar (Map.insert u value amap))
where
u = unsafePerformIO Unique.newUnique
merge :: Registrar a -> Registrar a -> Registrar a
merge = (<>)
delete :: Unique -> Registrar a -> Registrar a
delete signature (Registrar amap) =
Registrar (Map.delete signature amap)