更新:我注意到我的代码设计存在问题。我的代码的整体结构已经发生了很大变化,以至于对该问题的任何答案或多或少都与其当前状态无关。但SO表示最好不要删除已回答的问题,所以我会保留该问题。
我的代码的问题是类型类对于我想做的事情来说太通用了。现在我专注于编写
之类的函数makeModelId :: String -> Either StringValueError ModelId
然后将其扩展为:
makeModelIdM :: (Monad m) => String -> m (Either StringValueError ModelId)
makeModelIdM astr = do
idstr <- astr
return (makeModelId idstr)
我不确定这是否是最好的方法。
我知道有很多类似的问题,例如this或this或this,据我所知,{{1 }}。但是我似乎找不到确切的方法。
我基本上有一个setter类型类,它是
HUnit
我有几个实现这些类型类的数据类型,例如:
class StringLike2Primitive model where
fromString :: String -> model
fromText :: Text -> model
fromText aText = fromString (unpack aText)
class (StringLike2Primitive model) => StringLike2PrimitiveM model where
fromStringM :: (MonadPlus m) => String -> m model
fromTextM :: (MonadPlus m) => Text -> m model
fromStringM astr = return (fromString astr)
fromTextM aText = fromStringM (unpack aText)
我不确定如何在单元测试环境中针对受保护的值测试instance StringLike2Primitive ModelId where
fromString = StringIdCons
instance StringLike2PrimitiveM ModelId where
fromStringM aStr
| null aStr = fail "empty string is not allowed as id"
| not (isAlphaNumStr aStr) = fail
"Only ascii alphanumeric strings are allowed"
| not (isAsciiStr aStr) = fail
"Only ascii alphanumeric strings are allowed"
函数,并且我认为我的错误处理方法存在问题。任何提示将不胜感激。
答案 0 :(得分:0)
(这更多是评论,但也可能是答案。)
您确定需要第二类吗? fromStringM
的定义与其对StringLike2Primitive
实例的依赖程度不大,只是对其进行了包装。
fromStringM :: (Monad m, StringLike2Primitive a) => String -> m a
fromStringM a
| null a = fail "empty string is not allowed"
| not (isAlphaNumStr aStr) = fail "Only ascii alphanumeric strings are allowed"
| not (isAsciiStr aStr) = fail "Only ascii strings are allowed"
| otherwise = return $ fromString a
,对于fromText
同样如此。