这是我的代码的简化版本:
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
出现错误“预期类型:String,实际类型:IO String”。
====== 编辑 =======
这是有错误的“真实代码”(以及我从答案中得到的解决方案):
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]
最佳答案
您遗漏了从数据库中获取字符串的代码部分。无论哪种方式,您都需要从 IO String
中“解压”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 }
现在,从 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
失败的原因是因为您试图在纯函数中使用类型为 IO String
的 getLine
;因此 expected String, got IO String
错误消息。此外,该类型提到两个 String
作为输入,但您只接受一个。
关于haskell - IO monad 和记录语法的初学者错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8132000/