我如何克服长生不老药中的Protocol.UndefinedError?
How do I overcome Protocol.UndefinedError in elixir?
我正在为奶牛和公牛游戏编写代码。到目前为止,这是我的代码。
defmodule Demo do
def game() do
guess = 1234
secret = Enum.take_random(1..9, 4)
count(guess, secret)
end
defp count(guess, secret) do
Enum.zip(guess, secret)
|> Enum.reduce({0, 0}, fn {g, s}, {c, b} ->
cond do
g == s -> {c, b + 1}
g in secret -> {c + 1, b}
true -> {c, b}
end
end)
end
end
当我 运行 使用 IO.puts Demo.game
文件时,出现以下错误
(Protocol.UndefinedError) protocol Enumerable not implemented for 1234
(elixir) lib/enum.ex:1: Enumerable.impl_for!/1
(elixir) lib/enum.ex:141: Enumerable.reduce/3
(stdlib) lists.erl:1338: :lists.foreach/2
(elixir) lib/stream.ex:1157: Stream.do_zip/3
(elixir) lib/enum.ex:2802: Enum.zip/1
prog.ex:10: Demo.count/2
prog.ex:20: (file)
帮我了解我哪里出错了,以及如何清除错误
编辑:
我把条件改成了你建议的。但是我没有使用 Integer.digits 而是将随机生成的列表转换为字符串以使其可枚举,但我遇到了一个错误。代码如下所示。
defmodule Demo do
def game() do
guess = Integer.digits(1234)
secret = Enum.take_random(1..9, 4) |> Enum.map(&to_string/1)
numOfBullsCows(guess, secret)
end
def numOfBullsCows(guess, secret) do
Enum.zip(guess, secret)
|> Enum.reduce({0, 0}, fn
{g, g}, {c, b} -> {c, b + 1}
{g, _}, {c, b} when g in secret -> {c + 1, b}
_, {c, b}-> {c, b}
end)
end
结束
错误:
(ArgumentError) invalid args for operator "in", it expects a compile-time proper list or compile-time range on the right side when used in guard expressions, got: secret
(elixir) expanding macro: Kernel.in/2
prog.ex:14: Demo.numOfBullsCows/2
(elixir) expanding macro: Kernel.|>/2
prog.ex:12: Demo.numOfBullsCows/2
我还尝试了另一种方法,我创建了两个单独的函数来检查重复项,然后生成一个没有重复数字的随机数。
defmodule Main do
def noDuplicates(num) do
num_li = Integer.digits(num)
length(num_li) == length(Enum.uniq(num_li))
end
def generateNum() do
num = Enum.random(1000, 9999)
if noDuplicates(num) == true do
IO.puts(num)
else
generateNum()
end
end
end
但是我收到这样的错误
(UndefinedFunctionError) function Enum.random/2 is undefined or private. Did you mean one of:
* random/1
(elixir) Enum.random(1000, 9999)
prog.ex:8: Main.generateNum/0
prog.ex:17: (file)
(elixir) lib/code.ex:767: Code.require_file/2
Enum.zip/2
需要两个枚举作为参数,然后你传递 1234, [3, 5, 1, 6]
或类似的(后者是随机生成的 secret
,大小为 4
的列表)。
使用 Integer.digits/2
将整数拆分为数字,以便 Enum.zip/2
满意。
旁注:而不是使用cond/1
,使用多个函数子句
更符合习惯
...
|> Enum.reduce({0, 0}, fn
# ⇓ ⇓ same name matches when they are equal
{g, g}, {c, b} -> {c, b + 1}
# ⇓⇓⇓⇓ guard
{g, _}, {c, b} when g in secret -> {c + 1, b}
# catch-all
_, {c, b} -> {c, b}
end)
我正在为奶牛和公牛游戏编写代码。到目前为止,这是我的代码。
defmodule Demo do
def game() do
guess = 1234
secret = Enum.take_random(1..9, 4)
count(guess, secret)
end
defp count(guess, secret) do
Enum.zip(guess, secret)
|> Enum.reduce({0, 0}, fn {g, s}, {c, b} ->
cond do
g == s -> {c, b + 1}
g in secret -> {c + 1, b}
true -> {c, b}
end
end)
end
end
当我 运行 使用 IO.puts Demo.game
文件时,出现以下错误
(Protocol.UndefinedError) protocol Enumerable not implemented for 1234
(elixir) lib/enum.ex:1: Enumerable.impl_for!/1
(elixir) lib/enum.ex:141: Enumerable.reduce/3
(stdlib) lists.erl:1338: :lists.foreach/2
(elixir) lib/stream.ex:1157: Stream.do_zip/3
(elixir) lib/enum.ex:2802: Enum.zip/1
prog.ex:10: Demo.count/2
prog.ex:20: (file)
帮我了解我哪里出错了,以及如何清除错误
编辑:
我把条件改成了你建议的。但是我没有使用 Integer.digits 而是将随机生成的列表转换为字符串以使其可枚举,但我遇到了一个错误。代码如下所示。
defmodule Demo do
def game() do
guess = Integer.digits(1234)
secret = Enum.take_random(1..9, 4) |> Enum.map(&to_string/1)
numOfBullsCows(guess, secret)
end
def numOfBullsCows(guess, secret) do
Enum.zip(guess, secret)
|> Enum.reduce({0, 0}, fn
{g, g}, {c, b} -> {c, b + 1}
{g, _}, {c, b} when g in secret -> {c + 1, b}
_, {c, b}-> {c, b}
end)
end
结束
错误:
(ArgumentError) invalid args for operator "in", it expects a compile-time proper list or compile-time range on the right side when used in guard expressions, got: secret
(elixir) expanding macro: Kernel.in/2
prog.ex:14: Demo.numOfBullsCows/2
(elixir) expanding macro: Kernel.|>/2
prog.ex:12: Demo.numOfBullsCows/2
我还尝试了另一种方法,我创建了两个单独的函数来检查重复项,然后生成一个没有重复数字的随机数。
defmodule Main do
def noDuplicates(num) do
num_li = Integer.digits(num)
length(num_li) == length(Enum.uniq(num_li))
end
def generateNum() do
num = Enum.random(1000, 9999)
if noDuplicates(num) == true do
IO.puts(num)
else
generateNum()
end
end
end
但是我收到这样的错误
(UndefinedFunctionError) function Enum.random/2 is undefined or private. Did you mean one of:
* random/1
(elixir) Enum.random(1000, 9999)
prog.ex:8: Main.generateNum/0
prog.ex:17: (file)
(elixir) lib/code.ex:767: Code.require_file/2
Enum.zip/2
需要两个枚举作为参数,然后你传递 1234, [3, 5, 1, 6]
或类似的(后者是随机生成的 secret
,大小为 4
的列表)。
使用 Integer.digits/2
将整数拆分为数字,以便 Enum.zip/2
满意。
旁注:而不是使用cond/1
,使用多个函数子句
...
|> Enum.reduce({0, 0}, fn
# ⇓ ⇓ same name matches when they are equal
{g, g}, {c, b} -> {c, b + 1}
# ⇓⇓⇓⇓ guard
{g, _}, {c, b} when g in secret -> {c + 1, b}
# catch-all
_, {c, b} -> {c, b}
end)