好的,这一次我会说清楚,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
答案 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.STRef和Data.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)
...