绝对的Haskell初学者在这里。不太确定我在做什么。
我想创建并初始化对列表,然后对它们执行某些功能。我能够这样做:
type Btype = (Char,Bool)
svar :: Char -> [Btype] -> Bool
svar x [] = False
svar x ((a,b):xs) = if (x == a) then b
else svar x xs
bt = [('a', True), ('b', True), ('c', False), ('d', True), ('e', False)]
这有效并且做我想要的,而不是我想要的方式。
要使用此功能,我需要输入:
svar 'a' bt
我得到了True,这是标签的价值' a'所以它有效。
然而,我想要的是能够以某种方式将列表bt初始化,以便我可以以某种方式修改函数签名
(svar :: Char -> [Btype] -> Bool)
所以我不必输入:
svar 'a' bt
但只需输入
svar 'a'
并获得相同的结果。
我玩过数据关键字并尝试使用该功能的变体而没有运气。我也无法帮助我摆脱我的程序员逻辑"在我的脑海中尝试从功能编程的角度思考。所以,在这里度过一段艰难时期。
非常感谢任何提示/提示/解决方案。感谢。
答案 0 :(得分:3)
一种解决方案是使用currying将所需的列表bt
合并到函数中。为此,更改参数的顺序会更方便:
svar :: [Btype] -> Char -> Bool
svar [] _ = False
svar ((a,b):xs) x = if (x == a) then b
else svar xs x
然后用currying创建一个新函数:
svarbt = svar bt
现在bt
参数内置于新函数svarbt
中。仅使用一个参数调用此函数:
ghci> svarbt 'a'
True
编辑:这只是Neil Forrester在评论中提出的一种更为复杂的方式。
答案 1 :(得分:1)
涉及库函数的解决方案:
import Data.List
bt :: [(Char, Bool)]
bt = [('a', True), ('b', True), ('c', False), ('d', True), ('e', False)]
svar :: Char -> Bool
svar x = maybe False snd $ find ((==x) . fst) bt
svar
读作:find the first pair
fst
为==x
。这可能会导致找不到Nothing
,或找不到Just somePair
。在第一种情况下,返回False
,在第二种情况下,请snd somePair
。
一个常见的习语也是使用辅助函数,例如:(如Keshav Kini建议的那样)
svar :: Char -> Bool
svar x = go bt
where go :: [(Char, Bool)] -> Bool
go [] = False
go ((a,b) : rest) = if a == x then b else go rest
如果需要考虑效率,并且需要在长列表中执行许多查找,则应在Data.Map.Map
(具有O(log n)访问权限的平衡二叉搜索树)中对其进行转换。
import qualified Data.Map as M
btM :: M.Map Char Bool
btM = fromList bt
svar :: Char -> Bool
svar x = maybe False snd (lookup x btM)