我的代码中有以下反模式:
existsFunc :: Maybe Item -> Item
这是检查名称是否在Dictionary中的一段较大代码的一部分:
genFunc :: InputType -> Item
genFunc input = existsFunc(Data.Map.lookup input (myDictionary))
existsFunc :: Maybe Item -> Item
existsFunc (Just x) = x
existsFunc Nothing = error "input missing from dictionary"
我想用with代替上面的反模式!地图操作符,但我有困难理解语法。怎么能!应用?
genFunc :: InputType -> Item
genFunc input = ! Data.Map.lookup input (myDictionary) Error: element not in the map
genFunc input = Data.Map.lookup input (myDictionary)
编辑:
我还认为它可以以以下方式应用:
genFunc :: InputType -> Item
genFunc input = Data.Map.lookup input (myDictionary) ! input Error: element not in the map
genFunc input = Data.Map.lookup input (myDictionary)
像这样:
genFunc input = myDictionary Data.Map.! input
通常人们给Data.Map
模块起一个简短的名字,比如M
,使用如下的导入:
import qualified Data.Map as M
那么这个简短的版本是正确的:
genFunc input = myDictionary M.! input
可能根本不值得为这个函数命名。只要在你要使用genFunc
的地方使用M.!
。
请记住,!
和existsFunc
一样都是反模式。所以不要认为你在这里修复了——一个真正的修复涉及到从lookup
处理Nothing
。每个应用程序的需求各不相同;有时使用默认值是正确的,有时在某些包含单子中引发错误是正确的,有时将Maybe
传播到调用者的返回类型中是正确的,……还有其他的回应,我敢肯定。