Sag*_*tha -1 io monads haskell
我正在通过尝试创建一个查找.mp3和.flac元数据并将其整齐地写入文件的程序来练习Haskell。我已经走了这么远,但是我对应该做的事情感到很沮丧。这是这里的主要代码块:
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)
Run Code Online (Sandbox Code Playgroud)
我知道,这很混乱。在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
Run Code Online (Sandbox Code Playgroud)
我无法理解为什么会这样。在我的测试程序中运行类似的命令:
main = do
artg <- getTags "/home/spilskinanke/backlogtest/02 - await rescue.mp3" artistGetter
let test = init $ drop 8 $ show artg
print test
Run Code Online (Sandbox Code Playgroud)
这工作得很好。在我的ghci终端中输出字符串“ 65daysofstatic”。显然不是Char类型。那么为什么在我的代码中被称为Char?还要注意,在添加任何引用我正在使用的元数据模块的代码段(htaglib)之前,该程序在测试中运行良好。有了tagfiles函数和tagort monad,我可以为某个目录设置一个arg,并且我的测试将成功打印一个包含所有可读文件夹的FilePath列表,以及另一个包含所有以我想要的结尾的文件的FilePaths列表。 mlookup,在这种情况下为.mp3,.mp4,.flac和.wav。任何帮助,将不胜感激。
您正在混音,IO并且[]在tagsort:
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)
Run Code Online (Sandbox Code Playgroud)
该修补程序是简单的:用一个let语句而不是一个绑定声明<-,并添加pure作出IO String了的String您有:
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)
Run Code Online (Sandbox Code Playgroud)
一般来说,每个do块都必须位于一个monad中,直到您开始学习使用monad转换器组合不同的效果为止。因此,在一个IO块中,绑定语句右边的任何内容都必须是一个IO动作;如果您只想进行纯计算,则可以使用let(或者如果不需要将某些内容绑定到名称,则可以使用内联表达式)。最后,do块中的最后一条语句也必须是特定monad中的一个动作-这通常是一个纯值,只是用pure :: Applicative f => a -> f a(或包裹在monad中return :: Monad m => a -> m a,它具有相同的作用,但在更多情况下可以使用,因为限制性Monad约束)。
| 归档时间: |
|
| 查看次数: |
49 次 |
| 最近记录: |