所以我想使用关联列表(或映射)构建一个函数表。我做了一些简单的测试,发现以下内容:完全curried函数工作正常,但部分curried函数不能存储在关联列表中。以下代码运行正常:
import Data.List
import System.IO
func1 :: IO ()
func1 = putStrLn "1"
func2 :: IO ()
func2 = putStrLn "2"
funcTable = [ (1, func1)
, (2, func2)]
callFunc :: Int -> IO ()
callFunc i = do
let justFunc = lookup i funcTable
case justFunc of
Just func -> func
Nothing -> putStrLn "Wrong!"
main = do
callFunc 1
callFunc 2
callFunc 3
但是,以下代码将无法编译:
import Data.List
import System.IO
func1 :: IO ()
func1 = putStrLn "1"
func2 :: String -> IO ()
func2 s = putStrLn s
funcTable = [ (1, func1)
, (2, func2)]
callFunc :: Int -> IO ()
callFunc i = do
let justFunc = lookup i funcTable
case justFunc of
Just func1 -> func1
Just func2 -> func2 "OK"
Nothing -> putStrLn "Wrong!"
main = do
callFunc 1
callFunc 2
callFunc 3
我在代码中唯一没有编译的变化是我将func2更改为部分curried函数。任何让它运作的技巧?
答案 0 :(得分:2)
您的问题与将值应用于函数无关。问题是两个值都有不同的类型。 [(1,func1),(2,func2)]
的类型是什么? [(Int,IO ())]
? [(Int, String -> IO ())]
?两者都错了。
最简单的解决方案是将不同类型的值包装成新的值。
data Action
= SimpleAction (IO ())
| StringAction (String -> IO ())
table :: [(Int, Action)]
table = [(1, SimpleAction func1), (2, StringAction func2)]
callFunc :: Int -> IO ()
callFunc i = case lookup i table of
Just (SimpleAction action) -> action
Just (StringAction action) -> action "OK"
Nothing -> error "wrong"
请注意,func1
不是一个功能。