本文介绍了我如何验证Haskell的参数“public safe”构造函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 在我的 Python包中,我有一个函数用于创建经过验证的实例类,类似于 @staticmethod def config_enigma(rotor_names,window_letters,plugs,rings):'b $ b comps =(rotor_names +' - '+ plugs).split(' - ')[:: - 1] winds = [num_A0(c)for'A'+ window_letters +' A'] [:: - 1] rngs = [int(x)for x in('01。'+ rings +'.01')。split('。')] [:: - 1] 声明所有(名字在旋转中的名称在comps [1:-1])$ b $ b在反射器中声明comps [-1] 声明len(rngs)== len风)== len(comps)断言所有(rng中1 断言所有风(风中的chr_A0(风))风 #... 我想在Haskell中执行相同的行为。但是以相同的方式这样做(带断言)不起作用,因为一般情况下Haskell断言是被禁用的(除非设置了某些编译器标志)。例如,在像 $ b $ pref =lang-hs prettyprint-override> configEnigma rots winds plug rngs = ==(长度分量'))< $> [长度风',长度rng'])& (和$ [(> = 1),((和$(`M.member` comps )< $>尾部组件')) - ... 其中 rngs'=反向$(读< $>(splitOn。$01。 ++ rngs ++.01):: [Int]) winds'=A++反向风++A组件'=反向$ splitOn - $不能依赖于工作,因为断言将会在大多数情况下被删除。 什么是惯用的a nd可靠的方式来强制所有的实例在Haskell中验证(使用公共安全构造函数)?解决方案正常事情是明确表达失败。例如,可以写成: configEnigma :: ... - >也许... configEnigma ... = do guard(全部(((==)`on长度)组件')[winds',rngs']) guard(all (inRange(1,26))rngs') guard(all(`elem` letters)winds') guard(all(`M.member` comps)(tail components')) return ... 其中 ... 您甚至可能考虑对某些自定义类型错误从 Maybe 升级到 Except Error $ c>,以告诉来电者在施工过程中出了什么问题。然后,您可以使用像 $ b guard 除非(all(inRange(1,26))rngs')(throwError OutOfRange) configEnigma 的调用者必须表达如何处理失败。对于可能,这看起来像 $ b 案例configEnigma ... of Just v - > - 使用配置的enigma机器v Nothing - > - 失败案例;可能会打印一条消息给用户,并退出 ,同时使用除你得到了有关错误的信息: case runExcept(configEnigma ... ) Right v - > - 使用配置的enigma机器v Left err - > - 失败案例;根据错误告知用户究竟出了什么问题,然后退出 In my Python package I have a function I use to create validated instances of my class, with something like @staticmethoddef config_enigma(rotor_names, window_letters, plugs, rings): comps = (rotor_names + '-' + plugs).split('-')[::-1] winds = [num_A0(c) for c in 'A' + window_letters + 'A'][::-1] rngs = [int(x) for x in ('01.' + rings + '.01').split('.')][::-1] assert all(name in rotors for name in comps[1:-1]) assert comps[-1] in reflectors assert len(rngs) == len(winds) == len(comps) assert all(1 <= rng <= 26 for rng in rngs) assert all(chr_A0(wind) in LETTERS for wind in winds) #...and I would like to enforce the same behavior in Haskell. But doing so in the same way — with assertions — does not work, because Haskell assertions are disabled in general (unless certain compiler flags are set). For example, in something likeconfigEnigma rots winds plug rngs = assert ((and $ (==(length components')) <$> [length winds', length rngs']) && (and $ [(>=1),(<=26)] <*> rngs') && (and $ (`elem` letters) <$> winds') && (and $ (`M.member` comps) <$> tail components')) -- ... where rngs' = reverse $ (read <$> (splitOn "." $ "01." ++ rngs ++ ".01") :: [Int]) winds' = "A" ++ reverse winds ++ "A" components' = reverse $ splitOn "-" $ rots ++ "-" ++ plugcan't be relied on to work because the assertions will be removed in most contexts.What is an idiomatic and reliable way to force all my instances to be validated in Haskell (using a "public safe" constructor)? 解决方案 The normal thing is to express failure explicitly. For example, one might writeconfigEnigma :: ... -> Maybe ...configEnigma ... = do guard (all (((==) `on` length) components') [winds', rngs']) guard (all (inRange (1,26)) rngs') guard (all (`elem` letters) winds') guard (all (`M.member` comps) (tail components')) return ... where ...You might even consider upgrading from Maybe to Except Error for some custom-defined type Error, to communicate to the caller what it was that went wrong during construction. Then instead of guard, you could use a construction like: unless (all (inRange (1,26)) rngs') (throwError OutOfRange)The caller to configEnigma will have to express how to handle failures. For Maybe, this looks likecase configEnigma ... of Just v -> -- use the configured enigma machine v Nothing -> -- failure case; perhaps print a message to the user and quitwhile with Except you get information about what went wrong:case runExcept (configEnigma ...) of Right v -> -- use the configured enigma machine v Left err -> -- failure case; tell the user exactly what went wrong based on err and then quit 这篇关于我如何验证Haskell的参数“public safe”构造函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 10-15 00:21