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)
...
精彩评论