在Haskell列表中初始化值

时间:2014-08-24 06:30:40

标签: haskell

绝对的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' 

并获得相同的结果。

我玩过数据关键字并尝试使用该功能的变体而没有运气。我也无法帮助我摆脱我的程序员逻辑"在我的脑海中尝试从功能编程的角度思考。所以,在这里度过一段艰难时期。

非常感谢任何提示/提示/解决方案。感谢。

2 个答案:

答案 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)