Type synonym for Haskell giving type errors - haskell

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]

Related

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.

List of a Type Classe instance

I've been playing around with Haskell type classes and I am facing a problem I hope someone could help me to solve. Consider that I come from a Swift background and "trying" to port some of protocol oriented knowledge to Haskell code.
Initially I declared a bunch of JSON parsers which had the same structure, just a different implementation:
data Candle = Candle {
mts :: Integer,
open :: Double,
close :: Double
}
data Bar = Bar {
mts :: Integer,
min :: Double,
max :: Double
}
Then I decided to create a "Class" that would define their basic operations:
class GenericData a where
dataName :: a -> String
dataIdentifier :: a -> Double
dataParsing :: a -> String -> Maybe a
dataEmptyInstance :: a
instance GenericData Candle where
dataName _ = "Candle"
dataIdentifier = fromInteger . mts
dataParsing _ = candleParsing
dataEmptyInstance = emptyCandle
instance GenericData Bar where
dataName _ = "Bar"
dataIdentifier = fromInteger . mts
dataParsing _ = barParsing
dataEmptyInstance = emptyBar
My first code smell was the need to include "a" when it was not needed (dataName or dataParsing) but then I proceded.
analyzeArguments :: GenericData a => [] -> [String] -> Maybe (a, [String])
analyzeArguments [] _ = Nothing
analyzeArguments _ [] = Nothing
analyzeArguments name data
| name == "Candles" = Just (head possibleCandidates, data)
| name == "Bar" = Just (last possibleRecordCandidates, data)
| otherwise = Nothing
possibleCandidates :: GenericData a => [a]
possibleCandidates = [emptyCandle, emptyBar]
Now, when I want to select if either instance should be selected to perform parsing, I always get the following error
• Couldn't match expected type ‘a’ with actual type ‘Candle’
‘a’ is a rigid type variable bound by
the type signature for:
possibleCandidates :: forall a. GenericData a => [a]
at src/GenericRecords.hs:42:29
My objective was to create a list of instances of GenericData because other functions depend on that being selected to execute the correct dataParser. I understand this has something to do with the type class checker, the * -> Constraint, but still not finding a way to solve this conflict. I have used several GHC language extensions but none has solved the problem.
You have a type signature:
possibleCandidates :: GenericData a => [a]
Which you might thing implies that you can put anything in that list as long as it is GenericData. But that is not the way Haskell's type system actually works. The value possibleCandidates can be a list of any type which has a GenericData class but every element of the list must be of the same type.
What the GHC error message is telling you (in its own special way) is that the first element of the list is a Candle so it thinks that the rest of the list should also be of type Candle but the second element is actually a Bar.
Now there are ways to make heterogeneous lists (and other collections) in Haskell, but it is almost never the right thing to do.
One typical solution to this problem is to just merge everything down into one sum data type:
data GenericData = GenericCandle Candle | GenericBar Bar
You could even forgo the step of indirection and just put the Candle and Bar data directly into the data structure.
Now instead f a class you just have a datatype and your class functions become normal functions:
dataName :: GenericData -> String
dataIdentifier :: GenericData -> Double
dataParsing :: GenericData -> String -> Maybe a
dataEmptyInstance :: String -> GenericData
There are some other more complex ways to make this work, but if a sum data type fits the bill, use it. It is very common for parsers in Haskell to have a large sum data type (usually also recursive) as their result. Take a look at the Value type in Aeson the standard JSON library for an example.

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

Convert to typed value from String

I have file with list of values and types, after reading them I need to put them into db. For that, I need to supply insertion function with properly typed tuple, so I'm trying to convert values with something like this
toProperType :: String -> String -> a
toProperType tp val =
case tp of
"string" -> val -- ::String
"int" -> toIntType val -- ::Int64
"bigint" -> toIntType val -- ::Int64
"integer"-> toIntType val
"utcdate"-> toDateType val -- :: UTCTime
"double" -> toDoubleType val -- :: Double
Which is failing with
Couldn't match expected type ‘a’ with actual type ‘Double’
‘a’ is a rigid type variable bound by
which I think is correct.
What is proper way to achieve this functionality?
Maybe I need some extension or generate separate functions with TH(but not sure how to dispatch them)
The issue here is the meaning of -> a in your function type. If you're function actually had this type, then whoever called your function should be able to specify a concrete type of their choosing (that you may not even have in scope) and then expect your function to work as if it had the type
String -> String -> MyCustomType
However this clearly isn't what you had in mind. You don't mean "for all types a, I have a function ...", you mean "For any two strings, there is some type a for which I have a value". This idea, that you get to choose the type variable instead of the caller, is called "existential quantification" and GHC does support it. However I don't really think that's what you want to do. After all, when you go to actually use this function, you'll probably want to be able to case on whether or not you got back a UTCTime or a Double or something. Since you cannot do this with existential quantification (just like how you cannot case on type variables in polymoprhic functions) we should instead create a custom data type:
data Dyn = String String | Int Int | BigInt Integer | UTCDate UTCTime ...
and so on. That is, you list out an explicit constructor for each case that your type may return and then your function will read
toProperType :: String -> String -> Dyn
toProperType tp val =
case tp of
"string" -> String val -- ::String
"int" -> Int $ toIntType val -- ::Int64
"bigint" -> BigInt $ toIntType val -- ::Int64
"integer"-> Integer $ toIntType val
"utcdate"-> UTCDate $ toDateType val -- :: UTCTime
"double" -> Double $ toDoubleType val -- :: Double
This is how serious Haskell libraries handle things like JSON parsing or what not so you're in good company. Now it's well typed and whoever calls this function just cases on the Dyn value and decides what to do based on the returned type.

Haskell abstract datatypes and retrieving characters/defining as strings

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)

Resources