Skip to content

Instantly share code, notes, and snippets.

@miladhub
Created August 24, 2019 06:57
Show Gist options
  • Save miladhub/e039b38d1dcb24f4234da79d8780fe58 to your computer and use it in GitHub Desktop.
Save miladhub/e039b38d1dcb24f4234da79d8780fe58 to your computer and use it in GitHub Desktop.
haskell_testing.hs
import qualified Prelude
import Prelude hiding(readFile)
import Control.Monad.State
class Monad m => FSMonad m where
readF :: FilePath -> m String
numCharactersInFile :: FSMonad m => FilePath -> m Int
numCharactersInFile fileName = do
contents <- readF fileName
return (length contents)
instance FSMonad IO where
readF = Prelude.readFile
data MockFS = SingleFile FilePath String
newtype StateMockFS = State MockFS
instance FSMonad StateMockFS where
readF pathRequested = do
(SingleFile pathExisting contents) <- get
if pathExisting == pathRequested
then return contents
else fail "file not found"
testNumCharactersInFile :: Bool
testNumCharactersInFile = evalState
(numCharactersInFile "test.txt")
(SingleFile "test.txt" "hello world")
== 11
@Rotsor
Copy link

Rotsor commented Sep 3, 2019

This are couple of things that are wrong here.
The most basic is that you forgot to give the name to the newtype constructor. We can choose to call it StateMockFS too:

newtype StateMockFS = StateMockFS (State MockFS)

That's not right either because StateMockFS needs to be a type constructor, not a simple type:

newtype StateMockFS a = StateMockFS (State MockFS a)

That get us much closer, but now the compiler will ask us to implement the Monad, Applicative and Functor instances for StateMockFS, which you'll have to write (or derive using some of the language extensions).

@miladhub
Copy link
Author

miladhub commented Sep 4, 2019 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment