Reputation: 67
I am writing package manager and I stuck at checking is file installed.
[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)
Here is code of problematic function(s):
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
I were searching for solution but I cannot find anything.
Also, is there a way to convert string or text to FilePath?
Upvotes: 1
Views: 287
Reputation: 76300
The type of execParamStatement
in isFileInstalled
is:
execParamStatement :: SQLiteResult a => SQLiteHandle -> String -> [(String, Value)] -> IO (Either String [[Row a]])
that means that [(":path", f)]
is of type [(String, Value)]
and f
is dedecued to be of type Value
.
This all means that isFileInstalled
is deduced to take a Value
as first argument.
Now in the other installpkg
function you are calling:
mapM isFileInstalled (splitOn " " files)
and mapM
is deduced to be from:
mapM :: (Traversable t, Monad m) => (a -> m b) -> t a -> m (t b)
to:
mapM :: (Value -> IO b) -> [Value] -> IO [b]
for whatever b
is deduced there (it's hard to figure out because you don't put explicit type signatures for functions).
This all means that mapM
is expected to get a list of [Value]
from (splitOn " " files)
, which it's not. (splitOn " " files)
is returning a [String]
which is incompatible with [Value]
.
Since Value
has a constructor that takes a String
, you can use:
(map Text . splitOn " " $ files)
instead of:
(splitOn " " files)
and make it type check at least.
Also, is there a way to convert string or text to FilePath?
As far as FilePath
is concerned, that's just an alias for String
, so you don't need to convert to it to use it in the context where it's required a String
.
Finally for the sake of those reading the code and you reasoning about it, write top level types signatures for functions, thanks.
Upvotes: 3