Haskell abstract datatypes and retrieving characters/defining as strings - haskell

I had a datatype, example:
data MyData = Something1 String
and then I had a function
myFunction :: MyData -> String
myFunction x = x
within myFunction I want to refer to the characters ie ['S','o','m','e'......'1'] which are in my data type MyData. However, I get the following error:
Couldn't match expected type [Char]'
with actual typeMyData'
Expected type: String
Actual type: MyData
As far as I understand [Char] is the same as String, and I have declared 'Something1' as String, so it should work?

[Char] is the same as String, but neither is the same as MyData. To access the string stored within your data type, you'll need to use pattern matching:
myFunction :: MyData -> String
myFunction (Something1 xs) = xs
This is because the data keyword makes a completely new data type. If you only wanted an alias, you could also use the type keyword:
type MyData = String
myFunction :: MyData -> String
myFunction x = x

MyData is not the same as String. It is just very similar.
You can declare a type synonym like this:
type MyData = String
and then MyData and String are two names for the same type. In fact, String is already a type synonym of [Char]. In this case, myFunction is just the identity function id.
Or you can use pattern matching to extract the String from a MyData like this:
myFunction :: MyData -> String
myFunction (Something1 xs) = xs
Alternatively, you can use the record syntax to make the accessor automatically:
data MyData = Something1 { myFunction :: String}
(this is practically identical to declaring myFunction as above, except you can now construct MyDatas using the syntax Something1 { myFunction = x } as well as Something1 x)

Related

Using Either recursively

So I have defined a function like this one below:
myFunction :: String -> Either String MyType
I am reading String until the end. Left is used for handling errors. Right suppose to return me the tuple. In myFunction I am calling anotherFunction and checking if it returns Left or Right like this:
myFunction :: String -> Either String MyType
myFunction "" = Right -- want to return MyType here
myFunction s =
case anotherFunction s of
Left c -> Left c
Right (v1, v2, t) -> -- want to call myFunction again with t
When anotherFunction returns Right, I want to call myFunction again recursively without loosing v1 and v2. How can I achieve that with recursion?
Here is the exact definition of MyType:
data MyType = MyString String | MyInt Int | MyMap [(String, MyType)] deriving (Show, Eq)

What does such notation mean in haskell?

function :: Type1 Type2
Are Type1 and Type2 return values (tuples)?
data Loc = Loc String Int Int
data Parser b a = P (b -> [(a, b)])
parse :: Parser b a -> b -> [(a, b)]
parse (P p) inp = p inp
type Lexer a = Parser (Loc, String) a
item :: Lexer Char
item = ????
How should I return Lexer and Char from item function?
Could you please give me some simple example.
No, it is not a tuple, types can be parameterized as well. In imperative languages like Java, this concept is usually know as generic types (although there is no one-on-one mapping of the two concepts).
In Java for instance you have classes like:
class LinkedList<E> {
// ...
}
Now here we can see LinkedList as a function that takes as input a parameter E, and then returns a real type (for example LinkedList<String> is a linked list that stores Strings). So we can see such abstract type as a function.
This is a concept that is used in Haskell as well. We have for instance the Maybe type:
data Maybe a = Nothing | Just a
Notice the a here. This is a type parameter that we need to fill in. A function can not return a Maybe, it can only return a Maybe a where a is filled in. For example a Maybe Char: a Maybe type that is a Nothing, or a Just x with x a Char.

Passing any type in function signature in Haskell

I want to pass a function a wildcard or any type or even a way to choose between either of multiple types rather than just restrict it to String, or Number, or Boolean, for example:
myFunction :: a -> String
or
myFunction :: _ -> String
or
myFunction :: (String || Number) -> String
Is that possible?
myFunction :: a -> String is technically possible, however it's profoundly useless – since this must be able to deal with an argument of any type, there's nothing you can actually do with the argument. (It's a bit like getting a can with a completely unspecified substance – you wouldn't eat it in case it's corrosive, you couldn't use it for cleaning purposes in case it's fat, paint or glue, you couldn't process it further... in case of an unrestricted Haskell type you couldn't even analyse it.)
If you narrow it down to types that support some kind of common operation, a polymorphic argument can make sense:
myFunction' :: Show a => a -> String
myFunction' x = "The value is " ++ show x
Your other approach, supporting only two very specific types, is also possible:
myFunction'' :: Either String Integer -> String
myFunction'' (Left s) = "Got a string: “" ++ s ++ "”"
myFunction'' (Right n) = "Got a number: " ++ show n
Note that these two approaches are quite different: Show a => a -> String can be used as String -> String or as Integer -> String, or in fact any other type which supports the show operation (including newly-defined types of your own), but you must decide at compile-time which type you want. At runtime, all arguments passed to this function must then have the same type.
Either String Integer -> String can accept a mixture of String- and Integer values at runtime, but is always restricted to only these two types.
Defining a function a -> String is easily possible, it just won't be able to do anything useful unless you also restrict a to some typeclass (like Show).
_ -> String is not valid syntax. If it were, I imagine it would do the same as a -> String, so you can just use that.
(String || Number) -> String is also not valid syntax, but Either String Number -> String is. You can also define your data type with constructors for the types you want to allow.
myFunction :: a -> String means that myFunction can take an argument of any type, but will always return a string. This is legal Haskell syntax.
With PartialTypeSignatures enabled, myFunction :: _ -> String is legal Haskell syntax, with _ acting as a "hole", or a way to get the compiler to tell you what type it inferred at that position:
Temp.hs:4:15: warning: [-Wpartial-type-signatures]
• Found type wildcard ‘_’ standing for ‘String’
• In the type signature: myFunction :: _ -> String
|
4 | myFunction :: _ -> String
| ^
If you enable TypeOperators, then you can define type (||) = Either, which make myFuncion :: (String || Number) -> String mean that myFuncion is a function that takes an argument of type Either String Number and returns a String:
type Number = Integer
type (||) = Either
myFuncion = (String || Number) -> String
myFuncion (Left string) = string
myFuncion (Right number) = show number

Why is a String in Haskell recognized as (wrong) type [Char]?

I have a function
mytest :: Int -> String
mytest = "Test"
ghci refuses to load the file:
Couldn't match expected type ‘Int -> String’
with actual type ‘[Char]’
In the expression: "Test"
In an equation for ‘mytest’: mytest = "Test"
Failed, modules loaded: none.
Everything works once I add a wildcard operator:
mytest :: Int -> String
mytest _ = "Test"
Does anyone know why Haskell interprets the first "Test" as [Char] and the second one as String?
String is just an alias for [Char]. It is defined like this:
type String = [Char]
A list of Char constitutes an String.
Your original function didn't work because the type checker is trying to match "Test" which is a String or [Char] data type with Int -> String type which results in a type error. You can make it work either by returning a function of Int -> String type:
mytest :: Int -> String
mytest = \x -> show x
which can be also written as:
mytest :: Int -> String
mytest x = show x
Or as you have done:
mytest :: Int -> String
mytest _ = "Test" -- Return "Test" no matter what the input is

Type synonym for Haskell giving type errors

I am attempting to create a type synonym that looks something like this:
data Result = Either String [Token]
I'm having difficulty because while this code compiles, when I attempt to create a Result with a [Token], haskell complains
Not in scope: data constructor `Result'
How can I define a type synonym with a constructor that works?!
How are you trying to create a Result??
The correct way is:
If you declare it as a data:
data Result = Result (Either String [Token])
f :: Result
f = (Result (Left "test"))
Or, if you declare as a type:
type Result = Either String [Token]
f :: Result
f = Left "test"
With
type Result = Either String Token
the data constructors are
Left :: String -> Result
Right :: [Token] -> Result
because
data Either a b = Left a | Right b
With
data Result = Either String [Token]
you declare Result to have one two-argument constructor, Either with type
Either :: String -> [Token] -> Result
which is a) probably not what you want and b) confusing, because Either is a well-known type constructor.
I think you need to use type and not data
type Result = Either String [Token]

Resources