Why the newtype syntax creates a function - haskell

I look at this declaration:
newtype Parser a = Parser { parse :: String -> Maybe (a,String) }
Here is what I understand:
1) Parser is declared as a type with a type parameter a
2) You can instantiate Parser by providing a parser function for example p = Parser (\s -> Nothing)
What I observed is that suddenly I have a function name parse defined and it is capable of running Parsers.
For example, I can run:
parse (Parser (\s -> Nothing)) "my input"
and get Nothing as output.
How was this parse function got defined with this specific signature? How does this function "know" to execute the Parser given to it? Hope that someone can clear my confusion.
Thanks!

When you write newtype Parser a = Parser { parse :: String -> Maybe (a,String) } you introduce three things:
A type named Parser.
A term level constructor of Parsers named Parser. The type of this function is
Parser :: (String -> Maybe (a, String)) -> Parser a
You give it a function and it wraps it inside a Parser
A function named parse to remove the Parser wrapper and get your function back. The type of this function is:
parse :: Parser a -> String -> Maybe (a, String)
Check yourself in ghci:
Prelude> newtype Parser a = Parser { parse :: String -> Maybe (a,String) }
Prelude> :t Parser
Parser :: (String -> Maybe (a, String)) -> Parser a
Prelude> :t parse
parse :: Parser a -> String -> Maybe (a, String)
Prelude>
It's worth nothing that the term level constructor (Parser) and the function to remove the wrapper (parse) are both arbitrary names and don't need to match the type name. It's common for instance to write:
newtype Parser a = Parser { unParser :: String -> Maybe (a,String) }
this makes it clear unParse removes the wrapper around the parsing function. However, I recommend your type and constructor have the same name when using newtypes.
How does this function "know" to execute the Parser given to it
You are unwrapping the function using parse and then calling the unwrapped function with "myInput".

First, let’s have a look at a parser newtype without record syntax:
newtype Parser' a = Parser' (String -> Maybe (a,String))
It should be obvious what this type does: it stores a function String -> Maybe (a,String). To run this parser, we will need to make a new function:
runParser' :: Parser' a -> String -> Maybe (a,String)
runParser' (Parser' p) i = p i
And now we can run parsers like runParser' (Parser' $ \s -> Nothing) "my input".
But now note that, since Haskell functions are curried, we can simply remove the reference to the input i to get:
runParser'' :: Parser' a -> (String -> Maybe (a,String))
runParser'' (Parser' p) = p
This function is exactly equivalent to runParser', but you could think about it differently: instead of applying the parser function to the value explicitly, it simply takes a parser and fetches the parser function from it; however, thanks to currying, runParser'' can still be used with two arguments.
Now, let’s go back to back to your original type:
newtype Parser a = Parser { parse :: String -> Maybe (a,String) }
The only difference between your type and mine is that your type uses record syntax, although it may be a bit hard to recognise since a newtype can only have one field; this record syntax automatically defines a function parse :: Parser a -> (String -> Maybe (a,String)), which extracts the String -> Maybe (a,String) function from the Parser a. Hopefully the rest should be obvious: thanks to currying, parse can be used with two arguments rather than one, and this simply has the effect of running the function stored within the Parser a. In other words, your definition is exactly equivalent to the following code:
newtype Parser a = Parser (String -> Maybe (a,String))
parse :: Parser a -> (String -> Maybe (a,String))
parse (Parser p) = p

Related

Apply `a -> Maybe b` function to `Maybe a`

Say I have a function parse :: String -> Maybe (Integer, String) that parses the first integer i from a list of integers encoded as a string s like 1,2,3 and returns Just (i, s') where s' is the remaining string or Nothing if parsing failed.
How can I then concisely apply this function to a Maybe String? parse <$> maybeString has redundant type Maybe (Maybe (Integer, String)) and writing a custom pattern matching function for this seems to be overkill.
More generally: is there an equivalent to <$> of type (a -> f b) -> f a -> f b (or would that not make sense?).
EDIT: I'm stupid, I just realized there's Hoogle for this. Is this what we need Monads for? (I haven't reached that part of Haskell yet).
Sounds like you're looking for (>>=) which you can use like maybeString >>= parse. This requires the data type you're working with to be a Monad which Maybe satisfies.

How to create a newtype of parser?

newtype Parser a = PsrOf{
-- | Function from input string to:
--
-- * Nothing, if failure (syntax error);
-- * Just (unconsumed input, answer), if success.
dePsr :: String -> Maybe (String, a)}
I want to create a newtype of Parser to see how it looks like.
I tried
*ParserLib> PsrOf{"hello"}
But it comes up with an error
<interactive>:5:7: error: parse error on input ‘"’
You've already created the type. Now you want to create a value of that type. To do that, you need to call PsrOf with a value of type String -> Maybe (String, a). For example:
newtype Parser a = PsrOf { dePsr :: String -> Maybe (String, a) }
get3 :: String -> Maybe (String, Int)
get3 ('3':xs) = Just (xs, 3)
get3 _ = Nothing -- Any string, including the empty string, that doesn't start with '3'
get3P :: Parser Int
get3P = PsrOf get3
To actually use the parser, you need to extract the function before applying it to a string:
dePsr get3P "38" -- Just ("8", 3)
dePsr get3P "" -- Nothing
dePsr get3P "hello" -- Nothing
Record syntax here is just used to simplify the definition of the type, instead of writing
newtype Parser a = PsrOf (String -> Maybe (String, a))
dePsr :: Parser a -> String -> Maybe (String, a)
dPsr (PsrOf f) = f
The rest of the uses for record syntax (pattern matching or making slightly modified copies of a value) don't really apply usefully to types that wrap a single value.

Haskell parser combinator - do notation

I was reading a tutorial regarding building a parser combinator library and i came across a method which i don't quite understand.
newtype Parser a = Parser {parse :: String -> [(a,String)]}
chainl :: Parser a -> Parser (a -> a -> a) -> a -> Parser a
chainl p op a = (p `chainl1` op) <|> return a
chainl1 :: Parser a -> Parser (a -> a -> a) -> Parser a
p `chainl1` op = do {a <- p; rest a}
where rest a = (do f <- op
b <- p
rest (f a b))
<|> return a
bind :: Parser a -> (a -> Parser b) -> Parser b
bind p f = Parser $ \s -> concatMap (\(a, s') -> parse (f a) s') $ parse p s
the bind is the implementation of the (>>=) operator. I don't quite get how the chainl1 function works. From what I can see you extract f from op and then you apply it to f a b and you recurse, however I do not get how you extract a function from the parser when it should return a list of tuples?
Start by looking at the definition of Parser:
newtype Parser a = Parser {parse :: String -> [(a,String)]}`
A Parser a is really just a wrapper around a function (that we can run later with parse) that takes a String and returns a list of pairs, where each pair contains an a encountered when processing the string, along with the rest of the string that remains to be processed.
Now look at the part of the code in chainl1 that's confusing you: the part where you extract f from op:
f <- op
You remarked: "I do not get how you extract a function from the parser when it should return a list of tuples."
It's true that when we run a Parser a with a string (using parse), we get a list of type [(a,String)] as a result. But this code does not say parse op s. Rather, we are using bind here (with the do-notation syntactic sugar). The problem is that you're thinking about the definition of the Parser datatype, but you're not thinking much about what bind specifically does.
Let's look at what bind is doing in the Parser monad a bit more carefully.
bind :: Parser a -> (a -> Parser b) -> Parser b
bind p f = Parser $ \s -> concatMap (\(a, s') -> parse (f a) s') $ parse p s
What does p >>= f do? It returns a Parser that, when given a string s, does the following: First, it runs parser p with the string to be parsed, s. This, as you correctly noted, returns a list of type [(a, String)]: i.e. a list of the values of type a encountered, along with the string that remained after each value was encountered. Then it takes this list of pairs and applies a function to each pair. Specifically, each (a, s') pair in this list is transformed by (1) applying f to the parsed value a (f a returns a new parser), and then (2) running this new parser with the remaining string s'. This is a function from a tuple to a list of tuples: (a, s') -> [(b, s'')]... and since we're mapping this function over every tuple in the original list returned by parse p s, this ends up giving us a list of lists of tuples: [[(b, s'')]]. So we concatenate (or join) this list into a single list [(b, s'')]. All in all then, we have a function from s to [(b, s'')], which we then wrap in a Parser newtype.
The crucial point is that when we say f <- op, or op >>= \f -> ... that assigns the name f to the values parsed by op, but f is not a list of tuples, b/c it is not the result of running parse op s.
In general, you'll see a lot of Haskell code that defines some datatype SomeMonad a, along with a bind method that hides a lot of the dirty details for you, and lets you get access to the a values you care about using do-notation like so: a <- ma. It may be instructive to look at the State a monad to see how bind passes around state behind the scenes for you. Similarly, here, when combining parsers, you care most about the values the parser is supposed to recognize... bind is hiding all the dirty work that involves the strings that remain upon recognizing a value of type a.

String replace using map compilation error

I am new to Haskell, and trying to implement the code from here to replace strings using a map. I am getting an error message during compilation that says
* Expecting one more argument to `StringMap'
Expected a type, but `StringMap' has kind `* -> *'
* In the type signature:
stringMapReplace :: (Show stringMap) => StringMap -> String -> String
I have tried searching, but the only answer I can find for the error is that I'm not clarifying what type StringMap is. However, I thought that is what Show stringMap was doing.
import Data.Map
import Data.Strings
type StringMap stringMap = [(String, String)]
myStringMap =
[
("org1", "rep1"),
("org2", "rep2")
]
stringMapReplace :: (Show stringMap) => StringMap -> String -> String
stringMapReplace [] s = s
stringMapReplace (m:ms) s = strReplace ms (replace (fst m) (snd m) s)
main :: IO ()
main = do
putStrLn "Enter some text:"
putStrLn =<< stringMapReplace myStringMap <$> toUpper getLine
Note: strReplace comes from Data.Strings
I don't know if there is anything else wrong with the code, as the compiler is only giving the error above right now. If you notice anything else right off, please feel free to mention (or leave it for me to debug later as practice).
You defined the type synonym StringMap to take an (unused) type parameter stringMap. Type synonyms, as opposed to newtype, data, and GADT declarations, must always be fully applied. Thus every occurrence of StringMap must be have a parameter supplied, like forall a . StringMap a, StringMap Int, etc. In the signature of stringMapReplace, you do not give StringMap a parameter, hence the error.
Two options:
Change StringMap to type StringMap = [(String, String)], because it doesn't need a parameter.
Give StringMap a parameter in the signature of stringMapReplace. What parameter, you ask? Any one, because it is ignored. For example, the following should work:
stringMapReplace :: StringMap String -> String -> String

Unable to figure out what the type of a function is

I have this function:
import Data.Aeson
import Network.HTTP.Conduit
getJSON url = eitherDecode <$> simpleHttp url
which is called as:
maybeJson <- getJSON "https://abc.com" :: IO (Either String Value)
However, I can't figure out what the type of getJSON is. I've been trying these:
getJSON :: FromJSON a => String -> Either String a --1
getJSON :: String -> Either String Value --2
plus some other ones but failed. What is it?
The main thing you're missing in your attempts so far is the IO type. One correct type given your current usage is
getJSON :: String -> IO (Either String Value)
You can see that the IO type must be needed given your maybeJSON line - that makes it clear that getJSON <something> returns IO (Either String Value).
In fact the exact type is more general:
getJSON :: (FromJSON a, MonadIO m, Functor m) => String -> m (Either String a)
To go into more detail on how to derive the correct type, we need to look carefully at the types of simpleHttp and eitherDecode:
eitherDecode :: FromJSON a => ByteString -> Either String a
simpleHttp :: MonadIO m => String -> m ByteString
They're also being combined with (<$>) from Control.Applicative:
(<$>) :: Functor f => (a -> b) -> f a -> f b
Putting it all together gives the type above - the f for (<$>) and the m for simpleHttp must be the same, and the input type is the String being fed into simpleHttp, and the result type is the result type of eitherDecode, lifted into m by the (<$>) operation.
You can also just ask GHC to tell you the answer. Either load your module up in ghci and use :t getJSON, or leave out the type signature, compile with -Wall and look at the warning about the missing type signature for getJSON.
Note that you don't have to explicitly declare a type for your functions in Haskell. The compiler will deduce them for you. In fact, you can use the :type command (or just :t for short) in ghci to let the compiler tell you the type of a function after you load the source file.

Resources