How to convert a nested list of Chars to a String Haskell - string

I have a simple question, although Lists of Chars seem equivalent to Strings, they are not functionally working the same. if I have a nested List of Chars, of type [[Char]] that I would like to convert to a [String], how would I go about doing this?
When I try to perform a function on the [[Char]] and treat it as though it is a string I get:
Couldn't match expected type `([String] -> (Int, Int, Board)) -> t'
with actual type `[[Char]]'
When I try to declare that type String = [[Char]] I get:
Ambiguous occurrence `String'
It could refer to either `Main.String', defined at Testing.hs:19:1
or `Prelude.String',
imported from `Prelude' at Testing.hs:16:1-14
(and originally defined in `GHC.Base')

Those two types are completely identical, because String is a type synonym for [Char]. The definition of String is
type String = [Char]
The type keyword means it's a type synonym. A type synonym is always interchangeable with the type it is defined to be.
You can see this in GHCi like this (note that Haskell does not allow casting):
ghci> let test :: [Char]; test = "abc"
ghci> test :: String
"abc"
ghci> :t (test :: [Char]) :: String
(test :: [Char]) :: String :: String

When I try to declare that type String = [[Char]] I get:
Ambiguous occurrence `String'
It could refer to either `Main.String', defined at Testing.hs:19:1
or `Prelude.String',
imported from `Prelude' at Testing.hs:16:1-14
(and originally defined in `GHC.Base')
You are getting this error because your definition of String conflicts with the one already defined in base and exported by the Prelude. Remove your definition and use the one that already exists instead.

Related

IsString instance not automatically converted to String

I have a type a which is an instance of the IsString typeclass.
If I use something like
"foobar" :: a
everything works fine.
As soon as I use a function that returns a string, as in
("foo" ++ "bar") :: a
I get a compilation error telling me that
Couldn't match expected type ‘a’ with actual type ‘[Char]’
Expected type: a
Actual type: String
Notice that I have the {-# LANGUAGE OverloadedStrings #-} pragma.
Is there something else I should do to solve the compilation error?
The idea of the IsString typeclass is to specify that we can convert a String object to such object (with the fromString :: String -> a function). Furthermore by enabling the OverloadedStrings pragma, we can also write a objects as string literals (in that case these String literals will transparently be converted to as by calling the fromString function).
Note however that IsString does not results in a way to convert as back to Strings. Furthermore functions that are defined on Strings can not be used for such instances (at least not without doing some implementation work).
If you write:
("foo" ++ "bar") :: a
Haskell will derive that you call (++) :: [b] -> [b] -> [b], so as a result it knows that the type of these string literals is a IsString [b] => [b]. So that means that a ~ [b]. Since your type is probably not a list, there is no way that this can match.

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

Type Signature of functions with Lists in haskell

I am just beginning to learn Haskell and am following the book "Learnyouahaskell".I have come across this example
tell :: (Show a) => [a] -> String
tell [] = "The list is empty"
I understand that (Show a) here is a class constraint and the type of parameter , in this case a has to be able to be "showable" .
Considering that a here is a list and not an element of the list , why am i unable to declare the function like :-
tell :: (Show a) =>a->String
Edit 1:-from the answers below i seem to understand that one would need to specify the concrete type of a for pattern matching. Considering this,what would be a correct implementation of the below:-
pm :: (Show a) =>a->String
pm 'g'="wow"
It gives me the error as below
Could not deduce (a ~ Char)
from the context (Show a)
bound by the type signature for pm :: Show a => a -> String
at facto.hs:31:7-26
`a' is a rigid type variable bound by
the type signature for pm :: Show a => a -> String at facto.hs:31:7
In the pattern: 'g'
In an equation for `pm': pm 'g' = "wow"
Failed, modules loaded: none.
I understand from the error message that it s not able to deduce the concrete type of a , but then how can it be declared using Show.
I know I can solve the above like this:-
pmn :: Char->String
pmn 'g'="wow"
But I am just trying to understand the Show typeclass properly
List does implement Show type class but when you say: Show a => a -> String It means the function will accept any type which implements Show AND most importantly you can only call show class functions on a nothing else, your function will never know the concrete type of a. Whereas you are trying to call list pattern matching on a
Update for new edit in question:
The correct implementation would be: pm c ="wow". You can call any Show type class functions on parameter c. You cannot pattern match as you were trying before because you dont know the exact type of parameter, you only know that it implements Show type class. But when you specific Char as the type then the pattern matching works
In both signatures, a isn't a list -- it's any type at all, and you don't get to pick which (except that it must be an instance of Show).
In
tell₁ :: Show a => [a] -> String
tell₁ [] = "The list is empty"
... -- (remember to match the non-empty list case too!)
You're matching on the list of as, not on a value of type a itself.
If you wrote
tell₂ :: Show a => a -> String
tell₂ [] = "The list is empty"
...
You would be assuming that the type a is the type of lists (of something). But it could be any type at all, such as Bool.
(But it's possible that I don't understand your question -- you haven't really said what the problem is. When asking a question like this you should generally specify what you did, what you expected, and what happened. None of these is really specified here, so people can only guess at what you might've meant.)
The problem isn't with Show. Indeed if we try:
tell2 :: a -> String
tell2 [] = "The list is empty"
We get a type check error. Lets see what it says:
test.hs:5:7:
Couldn't match expected type `a' with actual type `[t0]'
`a' is a rigid type variable bound by
the type signature for tell2 :: a -> String at test.hs:4:10
In the pattern: []
In an equation for `tell2': tell2 [] = "The list is empty"
Now we ask ourselves, what is this does this so-called 'type' construct really mean? When you write tell2 :: a -> String, you are saying is that for any type that is exactly a, tell2 will give us a String. [a] (or [c] or [foo] - the name doesn't matter) is not exactly a. This may seem like an arbitrary distinction, and as far as I know, it is. Let's see what happens when we write
tell2 [] = "The list is empty"
> :t tell2
> tell2 :: [t] -> [Char]
As you well know there is no difference between writing t and a, and [Char] is just a type synonym for String, so the type we wrote and the type GHC infers are identical.
Well, not quite. When you, yourself, the programmer, specify the type of a function manually in your source, the type variables in your type signature become rigid. What does that mean exactly?
from https://research.microsoft.com/en-us/um/people/simonpj/papers/gadt/:
"Instead of "user-specified type", we use the briefer term rigid
type to describe a type that is completely specified, in some
direct fashion, by a programmer-supplied type annotation."
So a rigid type is any type specified by a programmer type signature.
All other types are "wobbly"[1]
So, just by virtue of the fact that you wrote it out, the type signature has become different. And in this new type grammar, we have that a /= [b]. For rigid type signatures, GHC will infer the very least amount of information it can. It must infer that a ~ [b] from the pattern binding; however it cannot make this inference from the type signature you have provided.
Lets look at the error GHC gives for the original function:
test.hs:2:6:
Could not deduce (a ~ [t0])
from the context (Show a)
bound by the type signature for tell :: Show a => a -> String
at test.hs:1:9-29
`a' is a rigid type variable bound by
We see again rigid type variable etc., but in this case GHC also claims it could not deduce something. (By the way - a ~ b === a == b in the type grammar). The type checker is actually looking for a constraint in the type that would make the function valid; it doesn't find it and is nice enough to tell you exactly what it would need to make it valid:
{-# LANGUAGE GADTs #-}
tell :: (a ~ [t0], Show a) => a -> String
tell [] = "The list is empty"
If we insert GHC's suggestion verbatim, it type checks, since now GHC doesn't need to make any inferences; we have told it exactly what a is.
As soon as you pattern match on 'g', eg
pm 'g' = "wow"
your function no longer has a type of (Show a) => a -> String; instead it has has a concrete type for 'a', namely Char, so it becomes Char -> String
This is in direct conflict with the explicit type signature you gave it, which states your function works with any type 'a' (as long as that type is an instance of Show).
You can't pattern match in this case, since you are pattern matching on an Int, Char, etc. But you can use the show function in the Prelude:
pm x = case show x of
"'g'" -> "My favourite Char"
"1" -> "My favourite Int"
_ -> show x
As you may have guessed, show is a bit magical ;). There's actually a whole bunch of show functions implemented for each type that is an instance of the Show typeclass.
tell :: (Show a) =>a->String
This says tell accepts a value of any type a that is showable. You can call it on anything showable. Which implies that inside the implementation of tell, you have to be able to operate on anything at all (that is showable).
You might think that this would be an okay implementation for that type signature:
tell [] = "The list is empty"
Because lists are indeed showable, and so are valid values for the first parameter. But there I'm checking whether the argument is an empty list; only values of the list type can be matched against list patterns (such as the empty list pattern), so this doesn't make sense if I'd called tell 1 or tell True or tell (1, 'c'), etc.
Inside tell, that type a could be any type that is an instance of Show. So the only things I can do with that value are things that are valid to do with all types that are instances of Show. Which basically means you can only pass it to other similar functions with a generic Show a => a parameter.1
Your confusion is stemming from this misconception "Considering that a here is a list and not an element of the list" about the type signature tell :: (Show a) => [a] -> String. Here a is in fact an element of the list, not the list itself.
That type signature reads "tell takes a single paramter, which is a list of some showable type, and returns a string". This version of tell knows it receives a list, so it can do listy things with its argument. It's the things inside the list which are members of some unknown type.
1 Most of those functions will also be unable to do anything with the value other than pass it on to another Show function, but sooner or later the value will either be ignored or passed to one of the actual functions in the Show typeclass; these have specialised implementations for each type so each specialised version gets to know what type it's operating on, which is the only way anything can eventually be done.

Haskell typing for Int's and Double's

Just quick question about typing.
If I type into ghci :t [("a",3)] I get back [("a",3)] :: Num t => [([Char], t)]
Inside a file I have defined a type as:
type list = [(String, Int)]
How can I change the type to support both Ints and Doubles with the type I have defined, similar to what I wrote in ghci?
First, you have an error in your code. Data types must start with capital letters:
type List = [(String, Int)]
(Note that String is a type synonym for [Char], i.e. they are exactly the same type). We'll solve your problem in a roundabout way. Note that you can make the type completely general in the second slot of the tuple:
type List a = [(String,a)]
so that your type parameterizes over arbitrary types. If you need to specialize to numeric types in some function, then you can make that specialization for each function individually. For example:
foo :: Num a => List a
foo = [("Hello",1),("World",2)]
We could have included a constraint in the data type, like this:
data Num a => List a = List [(String,a)]
but you would still have to include the constraint Num a => ... in every function declaration, so you don't actually save any typing. For this reason, Haskell programmers generally follow the rule "Don't include type constraints in data declarations."

Understanding type

A few questions about the Haskell programming language:
What's the difference between these two code statements? I'm convinced they should be the same:
type T = [Char]
type CurrentValue = Char
My concern is that, in the second one, there are no brackets.
Anyway, they are actually declarations, aren't they?
What is Maybe String?
For instance: type P = (Char, Maybe String)
Is that a function which has two arguments?
What is Maybe Char?
For instance : type D = ((Maybe Char) , Char)
It's another function taking three arguments, right?
What's the difference between these two code statements?
type T = [Char]
type CurrentValue = Char
The first line declares a type alias T for [Char] which is a list of characters.
The second line declares another type alias CurrentValue for Char, a single character.
What is Maybe String?
It is an application of the type constructor Maybe to the type String (which is just an alias for [Char]). It is similar to how the brackets turn a type into a list of that type, except Maybe makes things optional.
For instance: type P = (Char, Maybe String)
Is that a function which has two arguments ?
No, that's a tuple type of two elements. The first element is a Char and the second is a Maybe String.
What is Maybe Char ?
For instance : type D = ((Maybe Char) , Char)
It's another function having three arguments. Am I right?
This is again a tuple type. The type of first element is Maybe Char and the second is Char. The inner parenthesis are redundant, so it's the same as type D = (Maybe Char, Char).
Re 1) T is a type synonym for a list of characters ([Char]), whereas CurrentValue is a type synonym for single characters (Char).
More info: http://learnyouahaskell.com/making-our-own-types-and-typeclasses#type-synonyms
Re 2) Maybe a can have values of Just a or Nothing. Imagine a computation that could go wrong: if it passes, it will return the result wrapped in a Just, if it fails it will return Nothing. In this specific case it would return a String (which btw is a type synonym for [Char] too) wrapped in a Just.
GOA> Just "foo"
Just "foo"
GOA> :type Just "foo"
Just "foo" :: Maybe [Char]
Re 3) See the answer for question number two, but for a single character instead of a list of characters.
GOA> :type Just 'f'
Just 'f' :: Maybe Char
More info: http://en.wikibooks.org/wiki/Haskell/Hierarchical_libraries/Maybe
1) With type you can declare a type synonym. So with type T = [Char], T is a type synonym for [Char] (list of Chars; square brackets denote a list in Haskell), meaning that T can be replaced with [Char] anywhere in the program (and vice versa). So don't be concerned about the lack of brackets.
2) Maybe String is a type a value of which may contain a string, or not. Maybe is used like pointers are often used in languages like C: if a function returns a Maybe String, it means that the function either succeeded and returns a string, or it failed and doesn't return a string. You can read more about the Maybe type here.
With type P = (Char, Maybe String) a type synonym P is declared as a synonym for a tuple. The first element of the tuple has the type Char and the second has the type Maybe String.
3) type D = ((Maybe Char), Char), or type D = (Maybe Char, Char) (the inner parentheses are unnecessary), declares a type synonym for a tuple with Maybe Char and Char as inner types.
The type Char indicates one single character while [Char] indicates a list of characters (i.e. a string).
type T = [Char]
is equivalent to
type T = String
If you have a type t then, intuitively, Maybe t indicates a type that has the same values
of t plus an extra undefined value (Nothing).
In its use this corresponds (very) roughly to the null value for Java objects.
So while String and Char represent the string and character types, Maybe String and Maybe Char represent a string resp. chararacter that can also be non-defined.

Resources