初始化Haskell列表中的值

初始化Haskell列表中的值,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)

这里绝对是哈斯克尔初学者。我不太清楚我在做什么

我想创建和初始化一个配对列表,然后对它们执行某些功能。我可以这样做:

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
我得到了真值,这是标签“a”的值,所以它起作用了

然而,我想要的是能够以某种方式初始化列表bt,以便以某种方式修改函数签名

(svar :: Char -> [Btype] -> Bool) 
所以我不必键入:

svar 'a' bt
只是打字而已

svar 'a' 
得到同样的结果

我一直在玩弄data关键字,并尝试函数的变体,但运气不好。我似乎无法从头脑中摆脱“程序员逻辑”,尝试用函数式编程的方式来思考,这也无济于事。所以,在这里有点艰难


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

一个涉及库函数的解决方案:

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
被解读为:
查找第一对
,其中
fst
==x
。这可能会产生
未找到任何
,或
仅找到某对
。在第一种情况下,返回
False
,在第二种情况下,获取
snd somePair

一个常见的习惯用法也是使用helper函数,例如:(正如Keshav Kini所建议的)

如果效率是一个问题,并且您需要在一个长列表中执行许多查找,那么您应该在
Data.Map.Map
中对其进行转换(一个具有O(logn)访问的平衡二叉搜索树)


涉及库函数的解决方案:

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
被解读为:
查找第一对
,其中
fst
==x
。这可能会产生
未找到任何
,或
仅找到某对
。在第一种情况下,返回
False
,在第二种情况下,获取
snd somePair

一个常见的习惯用法也是使用helper函数,例如:(正如Keshav Kini所建议的)

如果效率是一个问题,并且您需要在一个长列表中执行许多查找,那么您应该在
Data.Map.Map
中对其进行转换(一个具有O(logn)访问的平衡二叉搜索树)


一种解决方案是使用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在其评论中建议的一种更为复杂的方法。

一种解决方案是使用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在其评论中建议的一种更复杂的方法。

svar的
svar
函数应该如何知道要查看哪个列表?还要注意,您基本上是在重写具有非常相似签名的列表。很明显,函数需要列表才能工作(记住haskell是纯的)因此,你唯一能做的事情就是逃到某个单子里——要么是状态/读取器单子,你可以在其中隐藏你的值,要么进入IO,然后用其他语言做所有你曾经做过的事情:PDo你需要
svar
来使用一个列表,而不是你在问题中写的列表,
bt
?如果没有,您可以使用where子句或let绑定将
bt
包含在
svar
的定义中。具体来说,您可以像这样实现Keshav Kini的建议:
svar2 x=svar x bt
,这将创建一个新函数
svar2
,该函数的行为与您描述的相同。
svar
函数应该如何知道要查看哪个列表?还要注意,您基本上是在重写具有非常相似签名的列表。很明显,函数需要列表才能工作(记住haskell是纯的)因此,你唯一能做的事情就是逃到某个单子里——要么是状态/读取器单子,你可以在其中隐藏你的值,要么进入IO,然后用其他语言做所有你曾经做过的事情:PDo你需要
svar
来使用一个列表,而不是你在问题中写的列表,
bt
?如果没有,您可以使用where子句或let绑定将
bt
包含在
svar
的定义中。具体来说,您可以像这样实现Keshav Kini的建议:
svar2 x=svar x bt
,这将创建一个新函数
svar2
,其行为与您描述的一样。酷,我同意尼尔·弗雷斯特的建议,但你的建议非常有帮助,我已经学习哈斯克尔几天了,在这个阶段任何东西都是有用的。谢谢。很好,我按照尼尔·弗雷斯特的建议去做了,但是你的建议非常有用,我已经学习哈斯克尔几天了,在这个阶段任何有用的东西都可以。非常感谢。