我是Elixir的新手(和功能性的)。我正在构建一个玩具扑克游戏,以便更熟悉该语言。当我编译此代码时,我收到以下错误:
** (BadArityError) #Function<12.99386804/2 in :erl_eval.expr/5> with arity 2
called with 1 argument ('SK')
每当我将列表作为参数传递时,似乎都会发生这种情况。错误发生在Hand.burn_cards
内。
import Enum
defmodule Deck do
def create do
for rank <- '23456789TJQKA', suit <- 'CDHS', do: [suit,rank] |> shuffle
end
def deal(deck, n) do
deck
|> shuffle
|> take(n)
end
end
defmodule Hand do
def burn_cards(current_hand, cards = []) do
Enum.filter(current_hand, fn (x, cards) -> x not in cards end)
end
end
hand = Deck.deal(deck = Deck.create, 5)
deck = deck -- hand
Hand.burn_cards(hand, [Enum.at(hand, 0)])
这是语言的一部分吗?或者我犯了错误?
答案 0 :(得分:4)
我可以看到您的代码存在两个问题:
首先,这一行
def burn_cards(current_hand, cards = []) do
意味着传入的第二个参数必须是空列表,但是您没有传入一个空列表,而是传递一个包含一个元素的列表。我相信你想用这个来代替
def burn_cards(current_hand, cards \\ []) do
表示默认值为空列表(如果省略),但也接受包含元素的列表。
其次是过滤部分
Enum.filter(current_hand, fn (x, cards) -> x not in cards end)
你不应该有卡片。相反,你应该尝试
Enum.filter(current_hand, fn (x) -> x not in cards end)
答案 1 :(得分:0)
我相信你的问题是传递给Enum.filter/2
的匿名函数的第二个参数。
看来这个函数必须只接收一个参数。这是,我们可以这样做:
iex(3)> pairs = [2, 4]
[2, 4]
iex(4)> Enum.filter([1, 2, 3, 4, 5], fn (x) -> x in pairs end)
[2, 4]
但不是这样:
iex(5)> pairs
[2, 4]
iex(6)> Enum.filter([1, 2, 3, 4, 5], fn (x, pairs) -> x in pairs end)
** (BadArityError) #Function<12.118419387/2 in :erl_eval.expr/5> with arity 2 called with 1 argument (1)
(elixir) lib/enum.ex:2857: Enum.filter_list/2
此问题的解决方案是使用第一种形式。那么你的Enum.filter
电话
可能看起来像这样:
Enum.filter(current_hand, fn (x) -> x not in cards end)
另外,我还有另一个问题:
** (FunctionClauseError) no function clause matching in Hand.burn_cards/2
The following arguments were given to Hand.burn_cards/2:
# 1
['7S', 'S5', 'S4', 'D7', 'H7']
# 2
['7S']
help.exs:16: Hand.burn_cards/2
(elixir) lib/code.ex:376: Code.require_file/2
这种情况正在发生,因为匹配cards = []
只有当卡片成功时才会成功
也是一个空列表。所以你的函数调用
Hand.burn_cards(hand, [Enum.at(hand, 0)])
永远不会匹配。您可能希望定义burn_cards/2
之类的
def burn_cards(current_hand, cards) do
Enum.filter(current_hand, fn (x) -> x not in cards end)
end
或者,如果你真的想确保cards
是一个列表,你可以这样做
def burn_cards(current_hand, cards) when is_list(cards) do
Enum.filter(current_hand, fn (x) -> x not in cards end)
end
希望我能提供帮助。 =)