Convert string to Foo (type string) - string

This example will be a little bare to strip out the custom xml parsing that I'm doing, but I've run into this issue:
package main
import (
"encoding/xml"
"fmt"
)
type Foo string
func main() {
var f Foo
var b string
c := xml.CharData{}
f = string(c)
b = string(c)
fmt.Println(b)
}
//prog.go:15: cannot use string(c) (type string) as type Foo in assignment
Foo is a type of string, what am I missing to convert the string representation of xml.CharData (which is valid, use it in many decoders) to a custom type which is a string?

Convert c to Foo directly.
f = Foo(c)
Playground: http://play.golang.org/p/WR7gCHm9El
Edit: This works because Foo is a string underneath. Foo is a new and distinct derived type; its base type is string. You can similarly make derived types for any existing type. Each derived type is distinct, so you get type safety. Conversions must be explicit.

Related

How do you define a function type in Haskell?

I'm trying to store a function type in a definition so I can reuse it, but Haskell doesn't let me do it. A function type is not a data type , nor a class, as far as I understand them. So what am I doing wrong please?
functionType = Int -> Int -> Int -> Int -> Int -> Int -> Int
myfunction :: functionType -- <-- how do I declare this thing in a definition?
myfunction a b c d e f = a*b*c*d*e*f
Type aliases use the type keyword in their declaration; also, as usual for the declaration of new type forms, the newly declared alias must start with an upper case letter*. So:
type FunctionType = Int -> Int -- -> ...
functionValue :: FunctionType
functionValue a = a
* ...or punctuation. Why doesn't the usual "upper-case" punctuation restriction apply? No idea. I never thought about it before trying to write this answer, and now that I have, I find that a bit weird. Perhaps the upper-case restriction on the declaration of new types should be removed!

Mandatory Maybes in the type system

I have something similar to the following
data A = A
{ id :: Integer
, foo :: Maybe String
, bar :: Maybe String
, baz :: Maybe String
}
This data is coming in to my service as JSON. This request is only considered valid when one or more of foo, bar, or baz are given. Is there a better way to express this within Haskell's type system?
Note: Unfortunately I am unable to make this separate requests. I'm just following a defined protocol.
http://hackage.haskell.org/package/these-0.4.2/docs/Data-These.html
import Data.These
data A = A
{ id :: Integer
, fooBarBaz :: These Foo (These Bar Baz)
}
type Foo = String
type Bar = String
type Baz = String
If it is not mandatory to have three separate fields with foo,bar and baz, I'd go with this, NonEmpty guarantees that there is at least one element, though there can of course be more.
import Data.List.NonEmpty
data Impression = Banner String | Video String | Native String
data A = A
{ id :: Integer
, fooBarBaz :: NonEmpty Impression
}
I would use a Map Field String with data Field = Foo | Bar | Baz (this can easily be replaced with String if needed, and then have:
data A = A
{ id :: Integer
, fields :: Map Field String
}
Now checking for the validity condition is as simple as:
isValid :: A -> Bool
isValid = not . Map.null . fields
Expanding on ʎǝɹɟɟɟǝſ's suggestion to use a map: there's also a type specifically for non-empty maps. (Note however that this sort of clashes with the more popular nonempty-list type from the semigroups library.)
import qualified Data.NonEmpty.Map as NEM
data Field = Foo | Bar | Baz
data A = A { id :: Integer
, fields :: NEM.T Field String
}
Consider giving one branch for each possible required field:
data A
= Foo
{ foo :: String
, barM, bazM :: Maybe String
}
| Bar
{ bar :: String
, fooM, barM :: Maybe String
}
| Baz
{ baz :: String
, fooM, barM :: Maybe String
}
It's a fair bit of boilerplate, but it's very direct and quite clear about what's required.

Haskell type with derived value

Is it possible to have a type preform a function one of its value to generate another one of it's values? For instance:
data Foo=Foo {valueOne::Int, valueTwo=valueOne*2} deriving (Bar)
Or am I thinking about this in the wrong way? Any help is appreciated!
If you always want the second field to depend on the first, just write a plain function:
data Foo = Foo { valueOne :: Int } deriving (Bar)
valueTwo :: Foo -> Int
valueTwo x = valueOne x * 2
The only difference is that the Bar instance, which is automatically generated, won't notice the second field.
If, instead, you want to generate values with such constraint, but still be able to sometimes disregard that, use a smart constructor:
data Foo = Foo { valueOne :: Int, valueTwo :: Int } deriving (Bar)
foo :: Int -> Foo
foo x = Foo x (2 * x)
If you use foo instead of Foo to construct new values, you will not need to pass the second argument, which will be derived from the first one.
Usually this is used in a module which does not export the constructor Foo, but exports the smart constructor foo. In this way the users of the module are constrained to build values satisfying the invariant, while the functions in the module can ignore it, when needed.

Why does this need an explicit type?

I wrote a generic type to type converter in Haskell using classes as follows:
{-# LANGUAGE FlexibleInstances #-}
class Convertable a where
convert::a
instance Convertable (Int -> String) where
convert = show
instance Convertable (String -> Int) where
convert = read
main = do
let result = ((+1) . convert :: String -> Int) "1"
print result
But I need the explicit type String -> Int in order to get it to work (which kind of negates the purpose of having a generic type converter....)
Why would this type declaration be needed at all, there is just one possibility that satisfies the types?
convert is not the problem here, numbers by default are of type Num a => a, so the problem here is +1 you have there. You have to give it a concrete type.
You can also just specify the type of result and ghc will infer the type of convert and of the Num instance for (+1):
main = do
let result :: Int
result = ((+1) . convert) "1"
print result

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