IO monad和记录语法的初学者错误

mrs*_*eve 2 io monads haskell

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

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

genBookmark :: String -> String -> IO Bookmark
genBookmark u l = return ( Bookmark { url = u, label = l } )
Run Code Online (Sandbox Code Playgroud)

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

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

genBookmark :: IO String -> IO String -> IO Bookmark
Run Code Online (Sandbox Code Playgroud)

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

genBookmark2 :: String -> String -> Bookmark
genBookmark2 u = return ( Bookmark { url = u, label = newlabel } )
                   where newlabel = getLine
Run Code Online (Sandbox Code Playgroud)

错误"预期类型:字符串,实际类型: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]
Run Code Online (Sandbox Code Playgroud)

Ada*_*ner 7

您遗漏了代码中从db获取字符串的部分.无论哪种方式,你需要String从你的"解包" IO String.

一般来说,你应该尽早摆脱它IO.所以你应该尝试一种类型的String -> String -> 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 }
Run Code Online (Sandbox Code Playgroud)

现在,从main它在IO,我们做我们的"分贝"要求让我们的字符串,解压的值,发送到我们的genBookmark功能.

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

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