开发者

Storing data in a table in Haskell

Okay, this time I'll make it clear, the job of function1 is to check a string if it comes up with the '?' thing, he will put the rest of the string in a list. if not, it will store everything in a stack, how can I do this

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 fro开发者_运维知识库m the token x


Firstly, please use a Data.Map to store the dictionary instead of a list of tuples to avoid O(N) look-up.

Haskell functions are pure, i.e. you shouldn't have mutable states. If you need to "store" something, it must appear in the argument list, e.g.

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

Alternatively, you could use monadic things like Data.STRef and Data.IORef to use mutable variables, but then some part of your code need to be wrapped in an ST or IO monad unnecessarily.


Appparently you want to cast a String ([Char]) into something|anything. That won't work. Formal reason: fun::a->b is not possible as b must occur somewhere in the arguments, otherwise it is not deductible. Informally: you cannot insure typesafety. Ex: your [Char] == "Hello world" and you attempt to cast it into a Int. BTW cast is C-speak for typeconversion.


The thing is that if x == '?', with the way that you have written it, function1 will return the same as function2. And if function2 returns nothing then function1 will do so to.

Since It's hard to deduce what you want to do, the short answer is no!

But don't give up! in any case there are things you can do that are actually quite nice. first of if you just want to know what function2 returns, and in the case that x is '?' return something else for function1 you do like this:

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

  where  fun2Returns = function2 xs

Now let's say that you want that to not return anything (thats return null in c-speak), you have to be explicit about that in you types, by using the Maybe type.

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


Something like?

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

function2 :: [Char] -> Maybe b

Update:

That doesn't look right (x :: String, but not Maybe a)

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

I guess it should look something like:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜