Rose Perrone
Rose Perrone

Reputation: 63616

Returning different values of the same data type:

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

Answers (2)

Rose Perrone
Rose Perrone

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

Jon Purdy
Jon Purdy

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

Related Questions