简体   繁体   中英

could someone explain this type error “Couldn't match expected type `IO ()' with actual type `a0 -> c0' ”

Here's the type error I am getting, followed by the code in question. This may be due to an incorrect use of function composition, if so I'd like an explanation as to how I can fix that. If it's something else, I'd like to talk about that too.

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

Failed, modules loaded: none.

 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
-- f .g . h -> f(g(h))

f . g . h f . g . h is not equivalent to f(g(h)) , it's equivalent to \\x -> f(g(hx)) , so h needs to be a function, but readJobFile (which is the h in your example) is an IO () . That's why the error message complains about expecting a function where you gave it an IO () .

As sepp2k said, fgh is a function, \\x -> f $ g $ hx . It seems that readJobFile is IO String , though, not IO () .

But it doesn't complain about expecting a function. It explains about having inferred a function, and having expected an IO () . It's inferred a function because your chain of compositions is just that---a function, so the result of applying makeJobState to a JobState value is (or would be) a function, not an IO action.

It seems as if what you want isn't function composition but monadic composition, something like makeJobState world = readJobFile >>= popProcessConfig >>= popJobState (with the world parameter actually being used at some point, though it's not really obvious to me where it should go. And that might not be the preferred order; it's hard to tell since the other two variables are undefined.) Since readJobFile is IO String , you'd want popProcessConfig to be String -> IO a and popJobState to be a -> IO () . That would result in an overall type of JobState -> IO () .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM