1

我想做这样的事情:

getValue :: Element -> String
getValue x = do
    v <- get UI.value x
    v

但是,会引发错误;的预期类型get UI.value x是,[String]但实际类型是UI String

但是,如果我将类型签名更改为getValue :: Element -> UI String,我的最后一个v得到预期类型的​​错误,UI String而它的实际类型是String.

我正在尝试实现这样的事情:

myfunction window = do
    words <- getElementsByClassName window "word"
    let strs = map getValue words

既然不能说let strs = map (\x -> v <- get UI.value x) words

当我只有一个元素要处理时,我很好:

filename <- chooser # get UI.value
liftIO $ print filename
unless (null filename) $ do
    prevRows <- getElementsByClassName w "row"
    mapM_ delete prevRows
    elems <- liftIO $ readJSON filename
    mapM_ (element table # addRow) elems
4

1 回答 1

3

由于get UI.value xhas typeUI String而不是String,因此正确的定义也getValue需要在UImonad 中:

-- Still not well-typed
getValue :: Element -> UI String
getValue x = do
    v <- get UI.value x
    v

但是,那么您的下一个问题是,在您绑定get UI.value x到之后vv有 type String,而不是UI String,所以您需要return它,从而导致正确的版本

getValue :: Element -> UI String
getValue x = do
    v <- get UI.value x
    return v

当然可以简化

getValue :: Element -> UI String
getValue x = get UI.value x

或 η-进一步减少到

getValue :: Element -> UI String
getValue = get UI.value

由于UI是一个 monad,你可以使用标准的 monad 组合器,比如mapM变成:getValue :: Element -> UI StringmapM getValue :: [Element] -> UI [String]

myfunction window = do
    words <- getElementsByClassName window "word"
    strs <- mapM (get UI.value) words
    -- ... rest of `myfunction` can use `strs`

请注意,myfunction当然仍然在UI.

于 2015-12-04T02:01:37.933 回答