11-- | This module defines types and functions for working with _foreign_
22-- | data.
3-
3+ -- |
4+ -- | `ExceptT (NonEmptyList ForeignError) m` is used in this library
5+ -- | to encode possible failures when dealing with foreign data.
6+ -- |
7+ -- | The `Alt` instance for `ExceptT` allows us to accumulate errors,
8+ -- | unlike `Either`, which preserves only the last error.
49module Foreign
510 ( Foreign
611 , ForeignError (..)
@@ -76,12 +81,20 @@ renderForeignError (ErrorAtIndex i e) = "Error at array index " <> show i <> ":
7681renderForeignError (ErrorAtProperty prop e) = " Error at property " <> show prop <> " : " <> renderForeignError e
7782renderForeignError (TypeMismatch exp act) = " Type mismatch: expected " <> exp <> " , found " <> act
7883
84+ -- | While this alias is not deprecated, it is recommended
85+ -- | that one use `Except (NonEmptyList ForeignError)` directly
86+ -- | for all future usages rather than this type alias.
87+ -- |
7988-- | An error monad, used in this library to encode possible failures when
8089-- | dealing with foreign data.
8190-- |
8291-- | The `Alt` instance for `Except` allows us to accumulate errors,
8392-- | unlike `Either`, which preserves only the last error.
8493type F = Except MultipleErrors
94+
95+ -- | While this alias is not deprecated, it is recommended
96+ -- | that one use `ExceptT (NonEmptyList ForeignError)` directly
97+ -- | for all future usages rather than this type alias.
8598type FT = ExceptT MultipleErrors
8699
87100-- | Coerce any value to the a `Foreign` value.
@@ -107,7 +120,7 @@ foreign import tagOf :: Foreign -> String
107120
108121-- | Unsafely coerce a `Foreign` value when the value has a particular `tagOf`
109122-- | value.
110- unsafeReadTagged :: forall m a . Monad m => String -> Foreign -> FT m a
123+ unsafeReadTagged :: forall m a . Monad m => String -> Foreign -> ExceptT ( NonEmptyList ForeignError ) m a
111124unsafeReadTagged tag value
112125 | tagOf value == tag = pure (unsafeFromForeign value)
113126 | otherwise = fail $ TypeMismatch tag (tagOf value)
@@ -122,52 +135,52 @@ foreign import isUndefined :: Foreign -> Boolean
122135foreign import isArray :: Foreign -> Boolean
123136
124137-- | Attempt to coerce a foreign value to a `String`.
125- readString :: forall m . Monad m => Foreign -> FT m String
138+ readString :: forall m . Monad m => Foreign -> ExceptT ( NonEmptyList ForeignError ) m String
126139readString = unsafeReadTagged " String"
127140
128141-- | Attempt to coerce a foreign value to a `Char`.
129- readChar :: forall m . Monad m => Foreign -> FT m Char
142+ readChar :: forall m . Monad m => Foreign -> ExceptT ( NonEmptyList ForeignError ) m Char
130143readChar value = mapExceptT (map $ either (const error) fromString) (readString value)
131144 where
132145 fromString = maybe error pure <<< toChar
133146 error = Left $ NEL .singleton $ TypeMismatch " Char" (tagOf value)
134147
135148-- | Attempt to coerce a foreign value to a `Boolean`.
136- readBoolean :: forall m . Monad m => Foreign -> FT m Boolean
149+ readBoolean :: forall m . Monad m => Foreign -> ExceptT ( NonEmptyList ForeignError ) m Boolean
137150readBoolean = unsafeReadTagged " Boolean"
138151
139152-- | Attempt to coerce a foreign value to a `Number`.
140- readNumber :: forall m . Monad m => Foreign -> FT m Number
153+ readNumber :: forall m . Monad m => Foreign -> ExceptT ( NonEmptyList ForeignError ) m Number
141154readNumber = unsafeReadTagged " Number"
142155
143156-- | Attempt to coerce a foreign value to an `Int`.
144- readInt :: forall m . Monad m => Foreign -> FT m Int
157+ readInt :: forall m . Monad m => Foreign -> ExceptT ( NonEmptyList ForeignError ) m Int
145158readInt value = mapExceptT (map $ either (const error) fromNumber) (readNumber value)
146159 where
147160 fromNumber = maybe error pure <<< Int .fromNumber
148161 error = Left $ NEL .singleton $ TypeMismatch " Int" (tagOf value)
149162
150163-- | Attempt to coerce a foreign value to an array.
151- readArray :: forall m . Monad m => Foreign -> FT m (Array Foreign )
164+ readArray :: forall m . Monad m => Foreign -> ExceptT ( NonEmptyList ForeignError ) m (Array Foreign )
152165readArray value
153166 | isArray value = pure $ unsafeFromForeign value
154167 | otherwise = fail $ TypeMismatch " array" (tagOf value)
155168
156- readNull :: forall m . Monad m => Foreign -> FT m (Maybe Foreign )
169+ readNull :: forall m . Monad m => Foreign -> ExceptT ( NonEmptyList ForeignError ) m (Maybe Foreign )
157170readNull value
158171 | isNull value = pure Nothing
159172 | otherwise = pure (Just value)
160173
161- readUndefined :: forall m . Monad m => Foreign -> FT m (Maybe Foreign )
174+ readUndefined :: forall m . Monad m => Foreign -> ExceptT ( NonEmptyList ForeignError ) m (Maybe Foreign )
162175readUndefined value
163176 | isUndefined value = pure Nothing
164177 | otherwise = pure (Just value)
165178
166- readNullOrUndefined :: forall m . Monad m => Foreign -> FT m (Maybe Foreign )
179+ readNullOrUndefined :: forall m . Monad m => Foreign -> ExceptT ( NonEmptyList ForeignError ) m (Maybe Foreign )
167180readNullOrUndefined value
168181 | isNull value || isUndefined value = pure Nothing
169182 | otherwise = pure (Just value)
170183
171- -- | Throws a failure error in `FT `.
172- fail :: forall m a . Monad m => ForeignError -> FT m a
184+ -- | Throws a failure error in `ExceptT (NonEmptyList ForeignError) m `.
185+ fail :: forall m a . Monad m => ForeignError -> ExceptT ( NonEmptyList ForeignError ) m a
173186fail = throwError <<< NEL .singleton
0 commit comments