在Haskell中的表中存储数据

时间:2010-07-03 05:11:04

标签: data-structures haskell

好的,这一次我会说清楚,function1的工作是检查一个字符串,如果它出现'?'事情,他会将其余的字符串放在一个列表中。如果没有,它会将所有内容存储在堆栈中,我该怎么做呢

function2 :: [String] -> [([Char], [Integer]->[Integer])] 
function1 :: [String] -> [Integer] -> ([Integer], String)
function1 [] stack = (stack, "")
function1 (x:xs) stack 
     | x == "?"           = function2 xs  -- # map the tokens after '?' to functions
                                          -- # and put them into dictionary for 
                                          -- # function1's later use
     | x == "m"           = function1 xs ((read x :: b):stack)
     | x == isJust lookup = eval xs (f stack)
     ...
     where lookup = -- # lookup(f) is the function that is mapped from the token x

4 个答案:

答案 0 :(得分:4)

首先,请使用Data.Map来存储字典而不是元组列表以避免O(N)查找。

Haskell函数是纯粹的,即你不应该有可变状态。如果你需要“存储”某些东西,它必须出现在参数列表中,例如

import qualified Data.Map as M

type Stack = [Integer]
type StackFunction = Stack -> Stack
type Token = String
type TokenMap = M.Map Token StackFunction
function2 :: [Token] -> TokenMap

function1_alt :: TokenMap -> [Token] -> Stack -> (Stack, Token)
function1_alt _ [] stack = (stack, "")
function1_alt map ("?":xs) stack = let newMap = function2 xs in
                                       function1_alt (M.union oldMap newMap) xs stack
-- #          pass the new changed map as an argument ^^^^^^^^^^^^^^^^^^^^^
function1_alt map ("m":xs) stack = function1_alt map xs ((read x):stack)
function1_alt map (x:xs) stack | isJust f  = eval xs (fromJust f $ stack)
                               | otherwise = ...
                              where f = M.lookup x map

function1 :: [Token] -> Stack -> (Stack, Token)
function1 = function1_alt M.empty

或者,您可以使用Data.STRefData.IORef之类的monadic来使用可变变量,但是代码的某些部分需要不必要地包装在ST或IO monad中。

答案 1 :(得分:1)

显然你想把一个String([Char])转换成什么东西。那不行。正式理由:fun :: a-> b是不可能的,因为b必须出现在参数的某个地方,否则它是不可扣除的。非正式地:你不能保证类型安全。例如:您的[Char] ==“Hello world”并尝试将其转换为Int。 BTW演员阵容是C-speak for typeconversion。

答案 2 :(得分:1)

问题是,如果x =='?',按照你编写的方式,function1将返回与function2相同的内容。如果function2没有返回任何内容,那么function1将执行此操作。

由于很难推断出你想做什么,简短的回答是否定的!

但不要放弃!无论如何,你可以做的事情实际上相当不错。首先,如果你只是想知道function2返回什么,在这种情况下 x是'?'为function1返回其他内容你喜欢这样:

function1 (x:xs) 
          | x == '?' = somethingElse
          | x == '3' = do something with fun2Returns        
        ...

  where  fun2Returns = function2 xs

现在让我们假设您不希望返回任何内容(在c-speak中为return null),您必须使用Maybe类型明确您的类型。

function1 :: String -> Maybe b
function1 (x:xs)
          | x == '?' = Nothing

答案 3 :(得分:1)

喜欢什么?

function1 :: [Char] -> b
function1 (x:xs)
  | x == '?' && isJust r = fromJust r where r = function2 xs

function2 :: [Char] -> Maybe b

<强>更新

看起来不对(x :: String,但不是Maybe a

 ...
 | x == isJust lookup = eval xs (f stack)
 ...
 where lookup = -- # lookup(f) is the function that is mapped from the token x

我想它应该看起来像:

 ...
 | maybe False (x ==) lookup = eval xs (f stack)
 ...