简体   繁体   中英

test haskell io for custom data type

Update : I noticed that there was a problem in the design of my code. The overall structure of my code has changed so much that any answer to this question would be more or less irrelevant to its current state. But SO says it's better not to delete an answered question, so I am keeping the question.

The problem with my code was that typeclasses were too generic for what I wanted to do. Now I concentrate on writting functions like

makeModelId :: String -> Either StringValueError ModelId

Then extend that with something like:

makeModelIdM :: (Monad m) => String -> m (Either StringValueError ModelId)
makeModelIdM astr = do
  idstr <- astr
  return (makeModelId idstr)

I am not sure if it is the best approach though..


I know that there are lots of similar questions to this like this or this or this , and as far I understood what I want to do can be achieved with HUnit . But I can't seem to find the exact way of doing it.

I basically have a setter typeclass which is

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)

And I have couple of data types which implement these typeclasses, for example:

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"

I am not sure how can I test fromStringM function against guarded values in a unit test environment, and I think my approach to error handling is problematic. Any tips would be appreciated.

(This is more of a comment, but might be an answer as well.)

Are you sure you need a second type class? The definition of fromStringM doesn't rely on the StringLike2Primitive instance so much as it simply wraps it.

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

and likewise for fromText .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM