Reputation: 63616
I'm writing a readValue
function that can return any of Value
's algebraic data types. The value constructors for Value
aren't exported, so how can I return a Value
?
Here's the documentation on Value.
Below is the function and the errors it produces:
readValue :: Label -> String -> Value
readValue label valueString =
case label of
"tags" -> (read valueString :: [String])
"text" -> (read valueString :: String)
src/Edit.hs:79:16:
Couldn't match type `Char' with `[Char]'
Expected type: [String]
Actual type: String
In the expression: (read valueString :: String)
In a case alternative: "text" -> (read valueString :: String)
In the expression:
case label of {
"tags" -> (read valueString :: [String])
"text" -> (read valueString :: String) }
Upvotes: 0
Views: 128
Reputation: 63616
Here's the solution:
instance Val Value where
val = id
cast' = Just
readValue :: Label -> String -> Value
readValue label valueString =
case label of
"tags" -> val (read valueString :: [String])
"text" -> val (read valueString :: String)
Upvotes: 1
Reputation: 55079
You have:
readValue :: Label -> Value
You want:
readValue :: Label -> String -> Value
But:
(read valueString :: [String])
Has type [String]
because that’s the type you gave it explicitly. Recall that ::
has the lowest precedence. So the compiler is trying to unify String -> [String]
with Value
. That’s the source of your first error. The second error is caused by the :: String
annotation on the second branch of the case
, asking the compiler to try to unify String
with [String]
, which too fails.
I suppose you want to wrap these values you’ve read into some of the Value
constructors, which are indeed exported by Data.Bson
, else you would be trying to return multiple different types from one function. But without knowing more about your problem, I can’t infer what you meant to do.
Upvotes: 1