Haskell-在列表Monad中需要[Char]时获取Char类型
我正在练习Haskell,尝试制作一个程序,查找.mp3和.flac元数据并将其整齐地写入文件。我一个人走了这么远,但我对我应该做什么感到很困惑。下面是代码的主要部分:Haskell-在列表Monad中需要[Char]时获取Char类型,haskell,io,monads,Haskell,Io,Monads,我正在练习Haskell,尝试制作一个程序,查找.mp3和.flac元数据并将其整齐地写入文件。我一个人走了这么远,但我对我应该做什么感到很困惑。下面是代码的主要部分: builddir xs = do writeto <- lastest getArgs let folderl b = searchable <$> (getPermissions b) let filel c = ((lastlookup mlookup c) &&
builddir xs = do
writeto <- lastest getArgs
let folderl b = searchable <$> (getPermissions b)
let filel c = ((lastlookup mlookup c) &&) <$> ((not <$> folderl c))
a <- listDirectory xs
listdirs <- filterM (folderl) (map ((xs ++ "/") ++) a)
filedirs <- filterM (filel) (map ((xs ++ "/") ++) a)
let tagfiles = mapM (tagsort) filedirs
putStrLn $ concat listdirs
putStrLn $ concat tagfiles
tagsort xs = do
nsartist <- getTags xs artistGetter
nsalbum <- getTags xs albumGetter
artist <- init $ drop 8 $ show nsalbum
album <- init $ drop 7 $ show nsalbum
(artist ++ " - " ++ album)
我知道,这很乱。在ghci中运行时,我得到以下信息:
• Couldn't match expected type ‘[Char]’ with actual type ‘Char’
• In the first argument of ‘(++)’, namely ‘artist’
In a stmt of a 'do' block: artist ++ " - " ++ album
In the expression:
do nsartist <- getTags xs artistGetter
nsalbum <- getTags xs albumGetter
artist <- init $ drop 8 $ show nsalbum
album <- init $ drop 7 $ show nsalbum
....
60 artist ++ " - " ++ album
我很难理解为什么会这样。在我的测试程序中运行类似命令:
main = do
artg <- getTags "/home/spilskinanke/backlogtest/02 - await rescue.mp3" artistGetter
let test = init $ drop 8 $ show artg
print test
这个很好用。在ghci中将字符串65daysofstatic打印到我的终端。它显然不是字符类型。那么为什么在我的代码中被称为Char呢?
还要注意,在添加引用元数据模块的任何代码之前,我正在使用htaglib,该程序在测试中运行良好。由于没有tagfiles函数和tagsort monad,我可以为某个目录设置一个arg,我的测试将成功打印一个包含所有可读文件夹的文件路径列表,以及另一个包含所有文件的文件路径列表,这些文件的结尾是我在mlookup中想要的,在本例中是.mp3、.mp4、.flac和.wav。任何帮助都将不胜感激。您在tagsort中混淆了IO和[]:
一般来说,每个do块必须在单个monad中,直到您开始学习如何使用monad transformers来组合不同的效果。因此,在IO块中,绑定语句右侧的任何内容都必须是IO操作;如果你只想做纯计算,你可以使用let或者仅仅是内联表达式,如果你不需要绑定某个名字的话。最后,do块中的最后一条语句也必须是特定monad中的一个操作。这通常是一个纯值,仅用pure::Applicative f=>a->f a或return::monad m=>a->m a包装在monad中,它做同样的事情,但由于更严格的Monad约束,在更少的上下文中工作。谢谢您的快速响应Jon!我想是时候休息一下了,因为现在我可以清楚地看到,在我运行的测试程序中,我实际上使用了let绑定,而在我的主要代码块中没有使用。不知道我怎么会错过!如果我有另一个与此非常相关的问题,我应该创建一个全新的线程还是在这里简单地提问?@Sagarmatha新问题应该是新问题。如果给每个顶级定义一个类型签名,您将得到更好的错误消息,并写出更好的问题。另外,当您只给出一段代码时,请确保1。显示您的导入和2。给出您编写的在片段中调用/使用但未在片段中定义的所有函数/值的类型签名。
tagsort xs = do
-- Okay, run IO action and bind result to ‘nsartist’
nsartist <- getTags xs artistGetter
-- Similarly for ‘nsalbum’
nsalbum <- getTags xs albumGetter
-- Mistaken: ‘init …’ returns a list, not an ‘IO’ action
artist <- init $ drop 8 $ show nsalbum
album <- init $ drop 7 $ show nsalbum
-- You are also missing a ‘pure’ or ‘return’ here
(artist ++ " - " ++ album)
tagsort xs = do
nsartist <- getTags xs artistGetter
nsalbum <- getTags xs albumGetter
let artist = init $ drop 8 $ show nsalbum
let album = init $ drop 7 $ show nsalbum
pure (artist ++ " - " ++ album)