我是Haskell的新手,我应该编写一个函数,在其参数中接受一个函数,使用它并返回一个函数,其行为根据我传入的函数而变化, 要明确:在我的应用程序中:一个简单的缓存服务器,我读取了一个上下文文件,所有参数中都是“LOG:active”如果日志处于活动状态我必须在屏幕上给出日志以进行调试,否则我什么都不写,我不想使用if-then链,因此我想写一个函数
setLogging a = do
if a
then let logging x = putStrLn x
in return logging
else let logging x = putStrLn ""
in return logging
我以这种方式doLog <- setLogging True
使用它并且它有效,我对应该返回删除功能的函数有问题
我的缓存中的旧元素:它必须包含多少元素由上下文决定;这是我的功能
--ritorna la funzione che riduce la cache in funzione dell environment
setTrimming a = do
if a=="active"
then let trimming c logging = reduceCache 9 logging c --è attivo lowbandwidth
in return trimming
else let trimming c logging = reduceCache 5 logging c --non è attivo lowbandwidth
in return trimming
reduceCache s log cache
| (M.size cache) >= s = do
log "LOG: ciao"
reduceCache s log (snd (M.deleteFindMin cache))
| otherwise = cache
当我在doTrimm <- setTrimming "active"
使用此功能时出现此错误
ghc --make "trimmer.hs" (in directory: /media/Volume/doc/progetti/haskell)
[1 of 1] Compiling Main ( trimmer.hs, trimmer.o )
trimmer.hs:33:31:
Couldn't match expected type `t1 -> t'
against inferred type `M.Map k a'
In the expression: reduceCacheLow 9 logging c
In the definition of `trimming':
trimming c logging = reduceCacheLow 9 logging c
In the expression:
let trimming c logging = reduceCacheLow 9 logging c
in return trimming
trimmer.hs:35:30:
Couldn't match expected type `t1 -> t'
against inferred type `M.Map k a'
In the expression: reduceCacheHigh 4 logging c
In the definition of `trimming':
trimming c logging = reduceCacheHigh 4 logging c
In the expression:
let trimming c logging = reduceCacheHigh 4 logging c
in return trimming
Compilation failed.
我该如何修复这个程序? 提前谢谢
答案 0 :(得分:7)
首先写出reduceCache
的类型可能会有所帮助。您当前的版本具有以下类型:
reduceCache :: (Monad (M.Map k)) => Int -> ([Char] -> M.Map k a1) -> M.Map k a -> M.Map k a
但我们知道第二个参数是String -> IO ()
类型的日志记录函数,所以有些错误。以下类型更有意义:
reduceCache :: Int -> (String -> IO ()) -> M.Map k v -> IO (M.Map k v)
如果我们正在执行日志记录功能,我们知道我们需要最终进入IO
monad。我们只需要对您的实现进行一次更改以匹配新签名:
reduceCache s log' cache
| M.size cache >= s = do
log' "LOG: ciao"
reduceCache s log' (snd $ M.deleteFindMin cache)
| otherwise = return cache
我们还可以简化set...
函数:
setLogging :: Bool -> String -> IO ()
setLogging True = putStrLn
setLogging False = const $ return ()
setTrimming :: String -> M.Map k v -> (String -> IO ()) -> IO (M.Map k v)
setTrimming "active" = \c logging -> reduceCache 9 logging c
setTrimming _ = \c logging -> reduceCache 5 logging c
这应该做你想要的。请注意,setLogging
和setTrimming
不再是monadic,因此您只需在doLog = setLogging True
- 表达式中写let doLog = setLogging True
(或do
)。