【问题标题】:beginner error with IO monad and record syntaxIO monad 和记录语法的初学者错误
【发布时间】:2011-11-15 05:43:04
【问题描述】:

这是我的代码的简化版本:

data Bookmark = Bookmark {
   url :: String
 , label :: String
 } deriving (Show)

genBookmark :: String -> String -> IO Bookmark
genBookmark u l = return ( Bookmark { url = u, label = l } )

但是Strings(url, label)在数据库中,所以我要处理IO String。我必须有一个非常简单的解决方案,但我没有看到它(而且广​​泛的网络搜索并没有让我到任何地方。)

基本上我想将我的代码更改为:

genBookmark :: IO String -> IO String -> IO Bookmark

这是另一个说明问题的版本:

genBookmark2 :: String -> String -> Bookmark
genBookmark2 u = return ( Bookmark { url = u, label = newlabel } )
                   where newlabel = getLine

出现错误“预期类型:字符串,实际类型:IO 字符串”。

====== 编辑 =======

这是出现错误的“真实代码”(以及我从答案中得到的解决方案):

getSkosConceptRight :: String -> IO SkosConcept
getSkosConceptRight catName = do
                      suConcepts <- getSubConcepts catName
                      concept <- getMainConcept catName 
                      return ( concept { subConcepts = suConcepts })

getSkosConceptWrong :: String -> IO SkosConcept
getSkosConceptWrong catName = return ( concept { subConcepts = suConcepts })
                        where suConcepts = getSubConcepts catName
                              concept = getMainConcept catName 

getMainConcept :: ShortUrl -> IO SkosConcept
getSubConcepts :: ShortUrl -> IO [SkosConcept]

【问题讨论】:

    标签: haskell io monads


    【解决方案1】:

    您已经遗漏了从数据库中获取字符串的代码部分。无论哪种方式,您都需要从您的IO String 中“解压”String

    一般来说,您应该尽早摆脱IO。所以你真的应该尝试一种String -&gt; String -&gt; Bookmark

    这是一个简单的例子:

    -- These will represent your 'get from the db' calls
    ioUrl :: IO String
    ioUrl = return "http://..."
    
    ioLabel :: IO String
    ioLabel = return "my label"
    
    genBookmark :: String -> String -> Bookmark
    genBookmark url label = Bookmark { url = url, label = label }
    

    现在,从IO 中的main 开始,我们进行“db”调用以获取我们的字符串、解包值并发送到我们的genBookmark 函数。

    main = do
        url <- ioUrl     -- here, we're removing the "http://..." from the IO String
        label <- ioLabel -- same here
        print (genBookmark url label)
    

    您的genBookmark2 失败的原因是您试图在纯函数中使用getLine,其类型为IO String;因此出现expected String, got IO String 错误消息。此外,该类型提到两个 Strings 作为输入,但您只接受一个。

    【讨论】:

    • 1000 次谢谢!从您的回答中,我立即看到了问题。我忘记在我的代码的一个函数中使用 do 表示法。这是一个带有 db 的 snap servlet,所以我只发布了小代码示例。
    • 请注意,genBookmark 毫无意义。它与书签相同。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-09
    • 2012-12-31
    • 1970-01-01
    • 2019-06-18
    • 2017-11-19
    • 2018-02-17
    • 2016-03-03
    相关资源
    最近更新 更多