无法匹配类型`[Char]'用'价值'

时间:2015-08-19 09:29:14

标签: haskell

我正在编写包管理器,我坚持检查是否安装了文件。

[1 of 1] Compiling Main             ( ../src/beaver.hs, ../src/.o/Main.o)
../src/beaver.hs:57:37:
Couldn't match type `[Char]' with `Value'
Expected type: [Value]
  Actual type: [[Char]]
In the second argument of `mapM', namely `(splitOn " " files)'
In a stmt of a 'do' block: mapM isFileInstalled (splitOn " " files)

以下是有问题的功能代码:

installpkg = do
          args <- getArgs
          pkgname <- readProcess "beaver-pkgname" [(args !! 1)] ""
          extractpkg pkgname
          files <- metaprop "files" pkgname
          mapM isFileInstalled (splitOn " " files)
 isFileInstalled f = do
            dbcon <- openConnection "/var/lib/beaver/pkgs.db"
            res <- execParamStatement dbcon "SELECT owner FROM files WHERE path = :path" [(":path", f)] :: IO (Either String [[Row Value]])
            when (null res) (putStrLn "file exists")
            closeConnection dbcon

我正在寻找解决方案但我找不到任何东西。

另外,有没有办法将字符串或文本转换为FilePath?

1 个答案:

答案 0 :(得分:3)

execParamStatement中的isFileInstalled类型为:

execParamStatement :: SQLiteResult a => SQLiteHandle -> String -> [(String, Value)] -> IO (Either String [[Row a]])

表示[(":path", f)]的类型为[(String, Value)]f的类型为Value

这意味着isFileInstalled被推断为以Value作为第一个参数。

现在在你正在调用的另一个installpkg函数中:

mapM isFileInstalled (splitOn " " files)

mapM推断出来自:

mapM :: (Traversable t, Monad m) => (a -> m b) -> t a -> m (t b)

为:

mapM :: (Value -> IO b) -> [Value] -> IO [b]

对于那里推断的b(由于你没有为函数设置显式类型签名,因此很难弄明白。)

这意味着mapM预计会从[Value]获取(splitOn " " files)的列表,但不是(splitOn " " files)[String]正在返回与[Value]不兼容的Value

由于String的构造函数需要(map Text . splitOn " " $ files) ,因此您可以使用:

(splitOn " " files)

而不是:

FilePath

并至少进行类型检查。

  

另外,有没有办法将字符串或文本转换为FilePath?

String而言,String的{​​{3}}是... <frameset rows="0,0,*" frameborder="no" border="0"> <frame name="applet_container" scrolling="no" marginwidth="0" marginheight="0" noresize src=""> <frame name="javascript_container" scrolling="no" marginwidth="0" marginheight="0" noresize src="js.do"> <frame name="main" scrolling="yes" noresize src="Loading.do" marginwidth="0" marginheight="0" frameborder="0"> </frameset> ... ,因此您不需要转换为它以在上下文中使用它它需要... function replaceMainPage() { parent.frames["main"].document.location.href = "/XXXForm.do"; } function formOnLoad() { setTimeout("replaceMainPage()", 500); } </script> </head> <body onLoad="formOnLoad()" BGCOLOR="#FFFFFF"> javascript container </body> </html>

最后,为了那些阅读代码和你推理的人,为函数编写顶级类型签名,谢谢。