Type mismatch in example from Learning Haskell through Data Analysis - haskell

I have a basic knowledge of Haskell (LYAH) and wanted to look at this book to expand my Haskell, plus the general topic is something I enjoy. However it didn't take long before I ran into a type issue :
applyToColumnInCSVFile :: ([String] -> b) -> FilePath -> String -> IO (Either String b)
applyToColumnInCSVFile func inFileName column = do
input <- readFile inFileName
let records = parseCSV inFileName input
return $ either handleCSVError (\csv -> applyToColumnInCSV func csv column) records
where
handleCSVError = Left "This does not appear to be a CSV file."
It complains that handleCSVError is expected to be Text.Parsec.Error.ParseError but actually is Either [Char] b0' .
This is where I hit a wall on trying to figure out the solution to these error messages. I can actually follow the code at a high level in this book, but if I make a small error in writing the code, or there is some other small problem I can not so easily recover.
In the above I have possibly narrowed it down to an issue with parseCSV because when I check that :
http://hackage.haskell.org/package/csv-0.1.2/docs/Text-CSV.html
It shows it can return a ParseError, but I don't know how to resolve the issue.

Let's focus on this part of your code:
return $ either handleCSVError (\csv -> applyToColumnInCSV func csv column) records
where
handleCSVError = Left "This does not appear to be a CSV file."
As #DanielWagner noted in the comments, you misquoted your error message which actually reads:
• Couldn't match expected type parsec3.1.13.0:Text.Parsec.Error.ParseError -> Either String b
with actual type Either [Char] b0
The error message continues to point you to your definition of handleCSVError. You didn't apply a type to it, but let's add one to make more sense of the error message:
return $ either handleCSVError (\csv -> applyToColumnInCSV func csv column) records
where
handleCSVError :: Either String _
handleCSVError = Left "This does not appear to be a CSV file."
I'm using a type hole for the right component of the either since we don't actually care what it is here, and remember that in Haskell [Char] and String are the same type.
Now, let's look at the type of either :: (a -> c) -> (b -> c) -> Either a b -> c.
The first argument of either is a function which takes in something of the left type of your Either, and returns the output type. But you've defined handleCSVError as a static function with no arguments. It has the correct output type c of Either String _ from your larger function, but doesn't specify the argument. There are two ways to fix this:
Use const: ... either (const handleCSVError) ...
Throw away the first argument in your definition of handleCSVError:
handleCSVError :: ParseError -> Either String _
handleCSVError _ = Left "This does not appear to be a CSV file."

Related

Haskell: Get caller function name

In Haskell, is there a way to get the caller function name? Of course I could hard-code it, but that turns into a maintenance burden: If someone were to rename the function, nothing is forcing them to rename the hard-coded name.
A contrived example:
f1 :: String
f1 = "f1" -- can this be automated?
You can do this with GHC's CallStack functionality.
import GHC.Stack ( HasCallStack, getCallStack, callStack )
foo :: HasCallStack => String -> String
foo s = let ((name, _):_) = getCallStack callStack
in s <> ": " <> name
main :: HasCallStack => IO ()
main = putStrLn $ foo "This string is being passed to"
Produces output This string is being passed to: foo
See my link above for a full description, but basically you can ask to have access to a (partial) call stack in a function by including a HasCallStack constraint. Then callStack gets a CallStack, which is isomorphic to [(String, SrcLoc)], where the first element of each pair is a function name; getCallStack converts the abstract CallStack type into an actual list of pairs.
(The docs seem to claim that HasCallStack constraints can be inferred, but in my very brief experiments that wasn't happening; if I used callStack in a function with no signature I was just getting an empty call stack; probably best to explicitly write a signature with a HasCallStack constraint)
A kernel of an idea: make f1 be a parameterized thing. This will make it possible to put the code name and the string representing the code name together, to reduce the chances that somebody renames one without the other. So:
f1Raw :: String -> String
f1Raw name = name
f1 :: String
f1 = f1Raw "f1"
With a bit of Template Haskell hackery, it is likely that you could make an interface withName :: String -> Q [Decl] or so that let you write something like this as a shorthand for this pattern:
-- f1Raw exactly as before
f1Raw :: String -> String
f1Raw name = name
-- this next line...
$(withName "f1")
-- ...would expand to these two:
-- f1 :: String
-- f1 = f1Raw "f1"
The behavior of withName would be, roughly:
Take the given String, append "Raw", and create a Name for the corresponding thing in the current module.
Use introspection to get the type of the raw thing, check that it starts out String -> ..., then strip the String -> bit and create a Decl that declares f1 :: ....
Implement f1 = f1Raw "f1" as a second Decl.

When I specify x has type a, why does Haskell try to infer it has type a0?

Sometimes I'll specify something's type in a signature as, say, a, and GHC will respond that it can't deduce that its type is a0. Is there a single reason this happens, or a number of different possible reasons? Sometimes I solve it, sometimes not; I'm hoping for a unified theory.
Here's a short example. (To see this code including comments explaining what it's trying to do, see here.)
{-# LANGUAGE MultiParamTypeClasses
, AllowAmbiguousTypes
, FlexibleInstances
, GADTs #-}
type SynthName = String
data Synth format where
Synth :: SynthName -> Synth format
data MessageA format where
MessageA :: String -> MessageA format
data MessageB format where
MessageB :: String -> MessageB format
class (Message format) a where
theMessage :: a -> String
instance (Message format) (MessageA format) where
theMessage (MessageA msg) = msg
instance (Message format) (MessageB format) where
theMessage (MessageB msg) = msg
play :: Message format m => Synth format -> m -> IO ()
play (Synth name) msg =
print $ name ++ " now sounds like " ++ theMessage msg
That produces the following error.
riddles/gadt-forget/closest-to-vivid.hs:38:42: error:
• Could not deduce (Message format0 m)
arising from a use of ‘theMessage’
from the context: Message format m
bound by the type signature for:
play :: forall format m.
Message format m =>
Synth format -> m -> IO ()
at riddles/gadt-forget/closest-to-vivid.hs:36:1-54
The type variable ‘format0’ is ambiguous
Relevant bindings include
msg :: m (bound at riddles/gadt-forget/closest-to-vivid.hs:37:19)
play :: Synth format -> m -> IO ()
(bound at riddles/gadt-forget/closest-to-vivid.hs:37:1)
These potential instances exist:
instance Message format (MessageA format)
-- Defined at riddles/gadt-forget/closest-to-vivid.hs:30:10
instance Message format (MessageB format)
-- Defined at riddles/gadt-forget/closest-to-vivid.hs:32:10
• In the second argument of ‘(++)’, namely ‘theMessage msg’
In the second argument of ‘(++)’, namely
‘" now sounds like " ++ theMessage msg’
In the second argument of ‘($)’, namely
‘name ++ " now sounds like " ++ theMessage msg’
|
38 | print $ name ++ " now sounds like " ++ theMessage msg
Message is a multi-parameter typeclass. In order to determine which instance to use, there needs to be a concrete choice for a and for format. However, the method
theMessage :: a -> String
doesn't even mention format, so we have no way of figuring out which concrete type to use to find an instance of Message. The ambiguous type error you presumably got was about this (but that can be a tricky error message, I don't blame you for just enabling the extension).
The quick fix is to manually specify the format variable using ScopedTypeVariables and TypeApplications (or adding a Proxy format argument to theMessage).
play :: forall format m. Message format m => Synth format -> m -> IO ()
play (Synth name) msg =
print $ name ++ " now sounds like " ++ theMessage #format msg
However, the Message class raises a red flag as a misuse of typeclasses. It's not always bad, but whenever you see a class whose methods all have types like
:: a -> Foo
:: a -> Bar
i.e. they take a single a in contravariant position, it's likely that you don't need a typeclass at all. It's often cleaner to transform the class into a data type, like so:
data Message format = Message { theMessage :: String }
wherein each method becomes a record field. Then concrete types that you instantiated, such as your MessageA, get "demoted" to functions:
messageA :: String -> Message format
messageA msg = Message { theMessage = msg }
Whenever you would have passed an a with a Message constraint, just pass a Message instead. a dissolves into nothingness.
After you do this factoring you might be noticing that a lot of what you have written is sort of tautological and unnecessary. Good! Remove it!
When type checking code involving polymorphic bindings, the type inference engine creates fresh type variables for each use of the binding.
Here's a concrete example:
show () ++ show True
Now, we know that show :: Show a => a -> String. Above the first call to show chooses a ~ (), the second one chooses a ~ Bool. Wait! That looks as a contradiction since () and Bool are distinct types, so they can not be both equal to a. Is that it?
Nah, it is not a contradiction... it looks clear that each call of show can make its choice of a independently. During type inference this is done, roughly, as follows.
For each call we generate a fresh type variable, by renaming universally quantified type variables in the polymorphic type at hand
-- for the first call
show :: Show a0 => a0 -> String
-- for the second call
show :: Show a1 => a1 -> String
Then, we simply pick a0 ~ () and a1 ~ Bool and we are done. The user never realized that this was going on under the hood.
In case there is a type error, however, the freshly generated variables can be reported to the user, revealing a piece of the underlying inference algorithm. For instance
show []
Here, two polymorphic values are used, so we generate fresh variables for both.
[] :: [a0]
show :: Show a1 => a1 -> String
To typecheck, we need a1 ~ [a0], so we end up with (after some context reduction, which does not matter now):
[] :: [a0]
show :: Show a0 => [a0] -> String
Good, we no longer have a1 around. But what about a0? We do not have found any specific value for a0. Indeed, we can not do that, since the code does not contain anything to force that choice: a0 remains an ambiguous type at the end.
This happens because [] can create a list of any type, while show can take a list of any type as input (as long as its element type is showable). But these constraints do not tell us what the type should be!
Concluding, the code is ambiguous, so we have to fix it by telling GHC what type we choose. Any of these would be fine
show ([] :: [Int]) -- choose a0 ~ Int
show ([] :: [Bool]) -- choose a0 ~ Bool
show ([] :: [Char]) -- choose a0 ~ Char
In your code
play :: Message format m => Synth format -> m -> IO ()
play (Synth name) msg =
print $ name ++ " now sounds like " ++ theMessage msg
there is nothing which forces theMessage msg to use the same format which appears in the type of play. It is perhaps "obvious" to you that it should be, but it is not the only possible choice.
Choosing the same format is tricky here since your class has ambiguous types. This could still be used by turning on TypeApplciations and AmbiguousTypes, but something tells me that your design might be wrong, so I am a bit cautious here to suggest a solution. What you are trying to achieve? Why does the type of the Message not mention format in any way?

Extracting Information from Haskell Object

I'm new to Haskell and I'm confused on how to get values out of function results. In my particular case, I am trying to parse Haskell files and see which AST nodes appear on which lines. This is the code I have so far:
import Language.Haskell.Parser
import Language.Haskell.Syntax
getTree :: String -> IO (ParseResult HsModule)
getTree path = do
file <- readFile path
let tree = parseModuleWithMode (ParseMode path) file
return tree
main :: IO ()
main = do
tree <- getTree "ex.hs"
-- <do something with the tree other than print it>
print tree
So on the line where I have the comment, I have a syntax tree as tree. It appears to have type ParseResult HsModule. What I want is just HsModule. I guess what I'm looking for is a function as follows:
extract :: ParseResult a -> a
Or better yet, a general Haskell function
extract :: AnyType a -> a
Maybe I'm missing a major concept about Haskell here?
p.s. I understand that thinking of these things as "Objects" and trying to access "Fields" from them is wrong, but I'd like an explanation of how to deal with this type of thing in general.
Looking for a general function of type
extract :: AnyType a -> a
does indeed show a big misunderstanding about Haskell. Consider the many things AnyType might be, and how you might extract exactly one object from it. What about Maybe Int? You can easily enough convert Just 5 to 5, but what number should you return for Nothing?
Or what if AnyType is [], so that you have [String]? What should be the result of
extract ["help", "i'm", "trapped"]
or of
extract []
?
ParseResult has a similar "problem", in that it uses ParseOk to contain results indicating that everything was fine, and ParseFailed to indicate an error. Your incomplete pattern match successfully gets the result if the parse succeeded, but will crash your program if in fact the parse failed. By using ParseResult, Haskell is encouraging you to consider what you should do if the code you are analyzing did not parse correctly, rather than to just blithely assume it will come out fine.
The definition of ParseResult is:
data ParseResult a = ParseOk a | ParseFailed SrcLoc String
(obtained from source code)
So there are two possibilities: either the parsing succeeded, and it will return a ParseOk instance, or something went wrong during the parsing in which case you get the location of the error, and an error message with a ParseFailed constructor.
So you can define a function:
getData :: ParseResult a -> a
getData (ParseOk x) = x
getData (ParseFailed _ s) = error s
It is better to then throw an error as well, since it is always possible that your compiler/interpreter/analyzer/... parses a Haskell program containing syntax errors.
I just figured out how to do this. It seems that when I was trying to define
extract :: ParseResult a -> a
extract (ParseResult a) = a
I actually needed to use
extract :: ParseResult a -> a
extract (ParseOk a) = a
instead. I'm not 100% sure why this is.

converting a list of string into a list of tuples in Haskell

I have a list of strings:
[" ix = index"," ctr = counter"," tbl = table"]
and I want to create a tuple from it like:
[("ix","index"),("ctr","counter"),("tbl","table")]
I even tried:
genTuple [] = []
genTuples (a:as)= do
i<-splitOn '=' a
genTuples as
return i
Any help would be appriciated
Thank you.
Haskell's type system is really expressive, so I suggest to think about the problem in terms of types. The advantage of this is that you can solve the problem 'top-down' and the whole program can be typechecked as you go, so you can catch all kinds of errors early on. The general approach is to incrementally divide the problem into smaller functions, each of which remaining undefined initially but with some plausible type.
What you want is a function (let's call it convert) which take a list of strings and generates a list of tuples, i.e.
convert :: [String] -> [(String, String)]
convert = undefined
It's clear that each string in the input list will need to be parsed into a 2-tuple of strings. However, it's possible that the parsing can fail - the sheer type String makes no guarantees that your input string is well formed. So your parse function maybe returns a tuple. We get:
parse :: String -> Maybe (String, String)
parse = undefined
We can immediately plug this into our convert function using mapMaybe:
convert :: [String] -> [(String, String)]
convert list = mapMaybe parse list
So far, so good - but parse is literally still undefined. Let's say that it should first verify that the input string is 'valid', and if it is - it splits it. So we'll need
valid :: String -> Bool
valid = undefined
split :: String -> (String, String)
split = undefined
Now we can define parse:
parse :: String -> Maybe (String, String)
parse s | valid s = Just (split s)
| otherwise = Nothing
What makes a string valid? Let's say it has to contain a = sign:
valid :: String -> Bool
valid s = '=' `elem` s
For splitting, we'll take all the characters up to the first = for the first tuple element, and the rest for the second. However, you probably want to trim leading/trailing whitespace as well, so we'll need another function. For now, let's make it a no-op
trim :: String -> String
trim = id
Using this, we can finally define
split :: String -> (String, String)
split s = (trim a, trim (tail b))
where
(a, b) = span (/= '=') s
Note that we can safely call tail here because we know that b is never empty because there's always a separator (that's what valid verified). Type-wise, it would've been nice to express this guarantee using a "non-empty string" but that may be a bit overengineered. :-)
Now, there are a lot of solutions to the problem, this is just one example (and there are ways to shorten the code using eta reduction or existing libraries). The main point I'm trying to get across is that Haskell's type system allows you to approach the problem in a way which is directed by types, which means the compiler helps you fleshing out a solution from the very beginning.
You can do it like this:
import Control.Monda
import Data.List
import Data.List.Split
map ((\[a,b] -> (a,b)) . splitOn "=" . filter (/=' ')) [" ix = index"," ctr = counter"," tbl = table"]

Haskell: Type Error in Explicitly Typed Binding

I'm trying to create a function that will remove all occurrences of a given character in a string, but being the Haskell amateur that I am, I've run into issues that are making it hard to sleep.
Here's my code:
remove:: Char -> String -> Int
remove[] = []
remove (char : list) = char : remove (filter (\elm -> not (char == elm) ) list)
With the type definitions in, I get the following error code:
ERROR "a5.hs":17 - Type error in explicitly typed binding
*** Term : char : list
*** Type : [a]
*** Does not match : Char
Can anyone please help?
The type signature says that remove takes two parameters, a Char and a String, and gives back an Int.
The error message refers to the second equation, which tries to match the first parameter (a Char) to (char : list) (a list).
Perhaps you meant
remove char list = ...
?
Further errors:
The first equation makes the same mistake (trying to match an empty list with the Char parameter).
Perhaps this should be
remove _ [] = ...
(_ means to match anything.)
The type signature says that the result is an Int, but your equations give a String result.
There are more mistakes. But that will get you started.
Edit: In response to your first comment:
The type signature should be
remove :: Char -> String -> String
remove takes a Char and a String and gives back a String.
When you put remove :: Char -> String, that means remove takes a Char and gives back a String.
(\elm -> flip (==) elm)
is the same as (\elm -> (==) elm)
is the same as (\elm birch -> (==) elm birch)
is the same as (\elm birch -> elm == birch)
is also the same as (==).
This expression has the type a -> a -> Bool, but you are passing it as the first parameter to filter, which expects a function with type a -> Bool (i.e. it wants a function that takes one parameter, not a function that takes two).
(This is what the error message is telling you about.)

Resources