Hi, I’m fairly new to PureScript and I’m trying to create a project for practicing purposes with examples and unit tests to get a more thorough understanding of the language. I’ve created my own versions of the data types Maybe and Either. I want to build a parser that disects multiple characters in a string. Here’s the code:
import Prelude (class Eq, class Ord, class Show, ($), (<), (>), (<>), (<<<), otherwise)
import Control.Applicative (class Applicative, pure)
import Control.Apply (class Apply, (<*>))
import Data.Bifunctor (class Bifunctor)
import Data.Functor (class Functor, map, (<$>))
import Data.Generic.Rep (class Generic)
import Data.Newtype (class Newtype)
import Data.Semigroup (class Semigroup)
import Data.Show.Generic (genericShow)
import Data.String.CodeUnits (uncons, fromCharArray)
import Data.Tuple (Tuple(..))
data MyMaybe a = Nothing | Just a
derive instance eqMyMaybe :: Eq a => Eq (MyMaybe a)
derive instance genericMyMaybe :: Generic (MyMaybe a) _
instance showMyMaybe :: Show a => Show (MyMaybe a) where
show = genericShow
instance functorMyMaybe :: Functor MyMaybe where
map f (Just x) = Just $ f x
map _ Nothing = Nothing
instance applyMyMaybe :: Apply MyMaybe where
apply (Just f) x = f <$> x
apply Nothing _ = Nothing
instance applicativeMyMaybe :: Applicative MyMaybe where
pure = Just
data Either a b = Left a | Right b
derive instance eqEither :: (Eq a, Eq b) => Eq (Either a b)
derive instance ordEither :: (Ord a, Ord b) => Ord (Either a b)
derive instance functorEither :: Functor (Either a)
derive instance genericEither :: Generic (Either a b) _
instance showEither :: (Show a, Show b) => Show (Either a b) where
show = genericShow
instance bifunctorEither :: Bifunctor Either where
bimap f _ (Left x) = Left $ f x
bimap _ g (Right y) = Right $ g y
instance applyEither :: Apply (Either a) where
apply (Right f) x = f <$> x
apply (Left y) _ = Left y
instance applicativeEither :: Applicative (Either a) where
pure = Right
type ParserState a = Tuple String a
class ParserError (e :: Type) where
eof :: e
data PError = EOF
derive instance genericPError :: Generic PError _
instance showPError :: Show PError where
show = genericShow
instance parserErrorPError :: ParserError PError where
eof = EOF
type ParseFunction e a = ParserError e => String -> Either e (ParserState a)
newtype Parser e a = Parser (ParseFunction e a)
instance functorParser :: Functor (Parser e) where
map f p = Parser \s -> map f <$> parse p s
instance applyParser :: Apply (Parser e) where
apply p1 p2 = Parser \s -> case parse p1 s of
Left err -> Left err
Right (Tuple s1 h) -> case parse p2 s1 of
Left err -> Left err
Right (Tuple s2 x) -> Right (Tuple s2 (h x))
instance applicativeParser :: Applicative (Parser e) where
pure x = Parser \s -> pure (Tuple s x)
parse :: ∀ e a. Parser e a -> ParseFunction e a
parse (Parser f) = f
parse' :: ∀ a. Parser PError a -> ParseFunction PError a
parse' = parse
char :: ∀ e. Parser e Char
char = Parser \s -> case uncons s of
Nothing -> Left eof
Just { head, tail } -> Right (Tuple tail head)
As soon as I try to compile this, I get the following error message:
[1/1 TypesDoNotUnify] src\Ch17.purs:160:3
160 Nothing -> Left eof
^^^^^^^
Could not match type
MyMaybe
with type
Maybe
while trying to match type MyMaybe t2
with type Maybe
{ head :: Char
, tail :: String
}
while checking that expression case (uncons s) of
Nothing -> Left eof
(Just { head: head, tail: tail }) -> (apply Right) ((...) head)
has type Either t0 (Tuple String t1)
in value declaration char
where t0 is an unknown type
t1 is an unknown type
t2 is an unknown type
Can anyone tell me how to solve this?