0

我有以下代码:

import Text.JSON

-- get the value in a JSON object that has this key
getByKey :: JSValue -> String -> Maybe JSValue
getByKey object key =
  case object of
    JSObject a ->
      getFirst keyValues keyMatches
      where keyValues = fromJSObject object
            keyMatches (key', value) = key == key'
    _ -> Nothing

-- get the first item in the list matching a predicate
getFirst :: [a] -> (a -> Bool) -> Maybe a
getFirst [] pred = Nothing
getFirst (x:xs) pred =
  case pred x of
    True -> Just x
    False -> getFirst xs pred

我想用它来访问任意 JSValue 中的值。但是,它不会编译:

Prelude> :load Example
[1 of 1] Compiling Main             ( Example.hs, interpreted )

Example.hs:8:26:
    Couldn't match expected type `JSValue'
                with actual type `(String, t0)'
    Expected type: JSValue -> Bool
      Actual type: (String, t0) -> Bool
    In the second argument of `getFirst', namely `keyMatches'
    In the expression: getFirst keyValues keyMatches

Example.hs:9:38:
    Couldn't match expected type `JSObject e0'
                with actual type `JSValue'
    In the first argument of `fromJSObject', namely `object'
    In the expression: fromJSObject object
    In an equation for `keyValues': keyValues = fromJSObject object
Failed, modules loaded: none.

我做错了什么?

编辑: Daniel Fischer 好心地指出fromJSObject object应该是fromJSObject a。但是,这还不足以让类型检查器满意:

[1 of 1] Compiling Main             ( Example.hs, interpreted )

Example.hs:8:16:
    Couldn't match expected type `JSValue'
                with actual type `(String, JSValue)'
    Expected type: [JSValue]
      Actual type: [(String, JSValue)]
    In the first argument of `getFirst', namely `keyValues'
    In the expression: getFirst keyValues keyMatches
Failed, modules loaded: none.
4

2 回答 2

5

为什么不简单地使用lookupPrelude 中的现有功能?

getByKey :: JSValue -> String -> Maybe JSValue
getByKey (JSObject obj) key = lookup key (fromJSObject obj)
getByKey _ _ = Nothing

此外,您的getFirst函数是Data.List.find(使用相反顺序的参数)。

于 2013-05-27T22:41:11.943 回答
3

的类型fromJSObject

fromJSObject :: JSObject e -> [(String, e)]

但在这条线上

where keyValues = fromJSObject object

你传一个JSValue。您只是使用了错误的标识符,就在您解构的正上方

case object of
  JSObject a ->

所以你JSObjecta

where keyValues = fromJSObject a

应该管用。

此外,getFirst是从.flip findfindData.List

于 2013-05-27T22:42:17.347 回答