2

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?

2 Answers 2

2

[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
Sign up to request clarification or add additional context in comments.

2 Comments

I should just tell you my overall problem, i want to create custom data types, but I need to be able to access the characters composing them (like Something1) in my code.
Ah, I think I see what you're trying to do. No, you cannot access the name of the constructor itself directly, although you can define a function myFunction (Something1 _) = "Something1". A more advanced option is to derive the Data and Typeable type classes. This will allow you to write myFunction x = showConstr (toConstr x), but it's the same thing under the hood, with the compiler creating the boilerplate for you.
2

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)

2 Comments

Hi Max, if i were to use type MyData = String, could I then declare which abstract types could be part of MyData using constructors? I want to declare MyData only allowed say Object1 | Object2 | Object3 and then being able to access those Objectx's, to retrieve their characters?
No. If you use type MyData = String, then MyData and String are exactly the same. I'm not sure what you mean by "retrieving Objectx's characters" though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.