这是我得到的类型错误,然后是相关代码。这可能是因为函数组合的使用不正确,如果是这样,我想解释一下如何解决这个问题。如果这是其他的话,我也想谈谈这个。
frameworkDaemon.lhs:125:5:
Couldn't match expected type `IO ()' with actual type `a0 -> c0'
In the expression: popJobState . popProcessConfig . readJobFile
In an equation for `makeJobState':
makeJobState world
= popJobState . popProcessConfig . readJobFile
where
readJobFile
= do { let ...;
.... }
where
getFileContents (x : xs) = readFile (ixiaRoot ++ "/" ++ (show x))
popProcessConfig = undefined
popJobState = undefined
失败,模块加载:无。
makeJobState :: JobState -> IO ()
makeJobState world =
popJobState . popProcessConfig . readJobFile -- f .g . h -> f(g(h))
where readJobFile = do
let directoryPath = ixiaRoot ++ "/jobs"
processedPath = map (directoryPath </>) . filter (`notElem` [".",".."])
jobFileNames <- processedPath <$> getDirectoryContents directoryPath
let numStrings = map (last . splitOn "/") jobFileNames
sortJobNumbers = map read numStrings :: [Int]
getFileContents $ sort $ sortJobNumbers
where getFileContents (x:xs) = readFile (ixiaRoot ++ "/" ++ (show x))
popProcessConfig = undefined
popJobState = undefined
答案 0 :(得分:5)
-- f .g . h -> f(g(h))
f . g . h
不等同于f(g(h))
,它相当于\x -> f(g(h x))
,因此h
需要是一个函数,但{{1} (示例中为readJobFile
)是h
。这就是为什么错误消息抱怨期望你给它一个IO ()
的函数。
答案 1 :(得分:3)
正如sepp2k所说,f.g.h
是一个函数\x -> f $ g $ h x
。 readJobFile
似乎IO String
,而不是IO ()
。
但它没有抱怨期待一个功能。它解释了推断一个函数,并期望IO ()
。它推断了一个函数,因为你的组合链只是一个函数,所以将makeJobState
应用于JobState
值的结果是(或将是)函数,而不是IO动作。
似乎你想要的不是函数组合而是monadic组合,类似于makeJobState world = readJobFile >>= popProcessConfig >>= popJobState
(world
参数实际上在某些时候被使用,尽管对我来说并不是很明显它应该去了。这可能不是首选的顺序;很难说,因为其他两个变量是未定义的。)由于readJobFile
是IO String
,你需要popProcessConfig
String -> IO a
和popJobState
为a -> IO ()
。这将导致整体类型为JobState -> IO ()
。