Tidak ada klausa fungsi, meskipun sepertinya ada?

Saya sangat menghargai bantuan dalam hal ini, ini adalah hal pertama yang saya coba lakukan dengan Elixir dan itu membuat saya bingung.

Jadi maksud saya adalah menangkap dari STDIN berulang kali, menguraikan input pengguna sebagai angka. Ketika pengguna akhirnya menekan enter tanpa memasukkan nomor, mereka mendapatkan jumlah dari semua nomor yang dimasukkan sejauh ini. Sederhana.

Jadi, inilah cara saya merencanakannya:

defmodule Solution do
  def main, do: scan(IO.read :line)
  def scan(line), do: scan(IO.read :line, Integer.parse line)
  def scan("\n", total), do: IO.puts(total)
  def scan(line, {total, _}) do
    final_total = Integer.parse(line) + Integer.parse(total)
    next_line = IO.read :line
    scan(next_line, final_total)
  end
end

Solution.main

Baris demi baris:

def main, do: scan(IO.read :line)

Untuk memulainya, panggil scan lewat satu baris dari stdin.

def scan(line), do: scan(IO.read :line, Integer.parse line)

Jika kita mendapatkan panggilan scan dengan satu argumen, parsing argumen tersebut sebagai bilangan bulat, dan teruskan ditambah baris stdin berikutnya ke scan/2.

def scan("\n", total), do: IO.puts(total)

Jika kita mendapat panggilan scan/2 dengan baris stdin kosong, cukup keluarkan argumen kedua, bilangan bulat total.

dan akhirnya

  def scan(line, {total, _}) do
    final_total = Integer.parse(line) + Integer.parse(total)
    next_line = IO.read :line
    scan(next_line, final_total)
  end

Kami mendapatkan baris dari stdin, dan tupel total bilangan bulat dan beberapa sampah. Total saat ini adalah baris tersebut (diuraikan sebagai int) ditambah total sebelumnya. Kami memanggil scan/2 lagi dengan saluran baru dari stdin dan total terbaru kami.

Semua logika tampaknya berlaku bagi saya. Tapi saya mendapatkan (FunctionClauseError) no function clause matching in IO.read/2. Pesan kesalahan Elixir tidak terlalu deskriptif, jadi saya kesulitan menyelesaikannya. Apa sebenarnya kesalahan yang saya lakukan?


person GreenTriangle    schedule 20.11.2016    source sumber


Jawaban (1)


Petunjuk terbesar di sini adalah 2 di (FunctionClauseError) no function clause matching in IO.read/2. Anda memanggil versi 2 arity dari IO.read alih-alih 1 (dengan argumen :line dan Integer.parse line), yang kemungkinan besar Anda inginkan. Ini karena Anda kehilangan sepasang tanda kurung di sekitar argumen IO.read di baris ke-3:

def scan(line), do: scan(IO.read :line, Integer.parse line)

Itu seharusnya:

def scan(line), do: scan(IO.read(:line), Integer.parse line)

Ini juga dianggap lebih idiomatis untuk memiliki tanda kurung di sekitar semua pemanggilan fungsi (setidaknya yang memiliki argumen) ketika Anda menyusunnya:

def scan(line), do: scan(IO.read(:line), Integer.parse(line))

Kesalahan di sini sedikit kurang jelas dibandingkan yang seharusnya (seperti gagal mengkompilasi) karena Solution.scan dan IO.read memiliki versi arity 1 dan 2.

person Dogbert    schedule 20.11.2016
comment
Oh, sial, aku benar-benar melewatkannya dan itu sangat masuk akal. Terima kasih untuk itu @Dogbert, hargai itu. - person GreenTriangle; 20.11.2016