ไม่มีฟังก์ชันประโยค แต่ดูเหมือนว่าจะมีแน่นอน?

ฉันขอขอบคุณความช่วยเหลือในเรื่องนี้ นี่เป็นสิ่งแรกที่ฉันพยายามทำกับ Elixir และมันทำให้ฉันผิดหวัง

ดังนั้นความตั้งใจของฉันคือการจับภาพจาก STDIN ซ้ำแล้วซ้ำเล่า โดยแยกวิเคราะห์อินพุตของผู้ใช้เป็นตัวเลข เมื่อผู้ใช้กด Enter โดยไม่ต้องป้อนตัวเลข ในที่สุด ผู้ใช้จะได้รับผลรวมของตัวเลขทั้งหมดที่ป้อนจนถึงตอนนี้ เรียบง่าย.

นี่คือวิธีที่ฉันวางแผน:

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

ทีละบรรทัด:

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

เริ่มต้นด้วยการโทร scan ผ่านหนึ่งบรรทัดจาก stdin

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

หากเราได้รับการเรียก scan ด้วยอาร์กิวเมนต์เดียว ให้แยกวิเคราะห์อาร์กิวเมนต์นั้นเป็นจำนวนเต็ม แล้วส่งต่อบวกบรรทัด stdin ถัดไปไปที่ scan/2

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

หากเราได้รับการเรียก scan/2 โดยที่บรรทัด stdin ว่างเปล่า ให้ส่งออกอาร์กิวเมนต์ที่สองซึ่งเป็นจำนวนเต็ม 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

เราได้รับบรรทัดจาก stdin และค่าทูเพิลของผลรวมจำนวนเต็มและขยะบางส่วน ผลรวมปัจจุบันคือบรรทัดนั้น (แยกวิเคราะห์เป็น int) บวกกับผลรวมก่อนหน้า เราโทร scan/2 อีกครั้งโดยขึ้นบรรทัดใหม่จาก stdin และผลรวมล่าสุดของเรา

ตรรกะทั้งหมดดูเหมือนจะยึดถือฉัน แต่ฉันได้รับ (FunctionClauseError) no function clause matching in IO.read/2 ข้อความแสดงข้อผิดพลาดของ Elixir อธิบายไม่ได้มากนัก ดังนั้นฉันจึงประสบปัญหาในการแก้ไข ฉันทำอะไรผิดกันแน่?


person GreenTriangle    schedule 20.11.2016    source แหล่งที่มา


คำตอบ (1)


คำใบ้ที่ใหญ่ที่สุดคือ 2 ใน (FunctionClauseError) no function clause matching in IO.read/2 คุณกำลังเรียกเวอร์ชัน 2 arity ของ IO.read แทนที่จะเป็น 1 (พร้อมอาร์กิวเมนต์ :line และ Integer.parse line) ซึ่งคุณน่าจะตั้งใจไว้มากที่สุด เนื่องจากคุณไม่มีวงเล็บคู่รอบอาร์กิวเมนต์สำหรับ IO.read ในบรรทัดที่ 3:

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

นั่นควรจะเป็น:

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

นอกจากนี้ยังถือว่าเป็นสำนวนมากกว่าที่จะมีวงเล็บรอบการเรียกใช้ฟังก์ชันทั้งหมด (อย่างน้อยก็มีข้อโต้แย้ง) เมื่อคุณทำการซ้อน:

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

ข้อผิดพลาดที่นี่ชัดเจนน้อยกว่าที่ควรจะเป็นเล็กน้อย (เช่น การคอมไพล์ล้มเหลว) เนื่องจากทั้ง Solution.scan และ IO.read มีเวอร์ชัน arity 1 และ 2

person Dogbert    schedule 20.11.2016
comment
โอ้ แดง ฉันพลาดเรื่องนั้นไปโดยสิ้นเชิง และมันก็สมเหตุสมผลดี ขอบคุณสำหรับ @Dogbert ขอบคุณมาก - person GreenTriangle; 20.11.2016