关联列表中的部分Curried函数(映射)

时间:2017-08-08 15:20:04

标签: haskell

所以我想使用关联列表(或映射)构建一个函数表。我做了一些简单的测试,发现以下内容:完全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函数。任何让它运作的技巧?

1 个答案:

答案 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不是一个功能。