2015-06-12 6 views
6

** Итак, я работал с Erlang раньше, и мне это очень удобно. Я просто пытаюсь узнать Эликсир.Почему я получаю FunctionClauseError ("no function clause matching") в этой программе Elixir, переведенной из Erlang?

Недавно я пытался перевести пример «ленивых продуктов общественного питания» в эликсир, и я озадачен тем, почему он либо не компилируется, либо компилируется с предупреждением и не работает. Что мне не хватает, здесь; Есть идеи? Код Эрл и «бежать» следующим образом: **

[email protected] ~/dev/erlang 
$ cat cater.erl 

    -module(cater). 
    -export([cater/1]). 
    cater(0) -> 1; 
    cater(N) when N>0 -> N + cater(N-1). 

[email protected] ~/dev/erlang 
$ erl 
Eshell V6.3 (abort with ^G) 
1> c("cater.erl"). 
{ok,cater} 
2> cater:cater(10). 
56 
3>* 

Когда я пишу Cater.ex как так, он получает сообщение об ошибке, что не имеет смысла для меня:

[email protected] ~/dev/elix 
$ cat Cater.ex 

    defmodule Cater do 
     def cut(0), do: 1 
     def cut(N) when N>0, do: N + cut(N-1) 
    end 

[email protected] ~/dev/elix 
$ iex 
Interactive Elixir (1.0.4) - press Ctrl+C to exit (type h() ENTER for help) 
iex(1)> c("Cater.ex") 
Cater.ex:1: warning: redefining module Cater 
Cater.ex:3: warning: this expression will fail with ArithmeticError 
[Cater] 
iex(2)> Cater.cut(10) 
** (FunctionClauseError) no function clause matching in Cater.cut/1 
    Cater.ex:2: Cater.cut(10) 
iex(2)> 
+3

Arrrrgh! Какой я идиот. Как только я опубликовал это, у меня появилось «чувство», вернулось и отредактировано, и «достаточно», эликсиру не понравился тот факт, что мои переменные имена были капитализированы. Как только я изменил все Ns на n, он правильно скомпилирован и запущен. Так жаль беспокоить y'all – jpsthecelt

+1

Случается лучшим из нас :) – jjbohn

+2

Возможно, вы могли бы сменить название, чтобы люди могли легко получить сообщение: у меня также была эта проблема с попыткой эликсира, где все напоминает erlang, но все по-другому: o) – Pascal

ответ

7

Чтобы развернуть проблему, и почему вы получили сообщение об ошибке:

Заглавные идентификаторы рассматриваются как псевдонимы для атомов. Например:

iex(1)> N == :Elixir.N 
true 

Так что, когда у вас есть следующий код:

iex(1)> defmodule Test do 
...(1)> def foo, do: IO.puts "testing" 
...(1)> end 
iex(2)> Test.foo 
testing 

Это то же самое, как говорят

iex(3)> :Elixir.Test.foo 
testing 

Поскольку прописные идентификаторы рассматриваются как символы, вы, по сути написал следующее программа:

defmodule Cater do 
    def cut(0), do: 1 
    def cut(:Elixir.N) when :Elixir.N>0, do: :Elixir.N + cut(:Elixir.N-1) 
end 

Это допустимо, так как вы можете сопоставлять шаблон по атомам в списке аргументов, а :Elixir.N > 0 - допустимое выражение.

iex(1)> N > 0 
true 

Рассмотрим следующую программу Elixir и вывод:

iex(1)> defmodule Cater do 
...(1)> def cut(0), do: IO.puts "cut(0)" 
...(1)> def cut(N) when N > 0, do: IO.puts "cut(N)" 
...(1)> end 
iex(2)> Cater.cut(0) 
cut(0) 
iex(3)> Cater.cut(N) 
cut(N) 
iex(4)> Cater.cut(:Elixir.N) 
cut(N) 
iex(5)> Cater.cut(1) 
** (FunctionClauseError) no function clause matching in Cater.cut/1 
    iex:2: Cater.cut(1) 

Итак, причина вы получили сообщение, казалось бы, странный ошибки no function clause matching in Cater.cut/1 что нет технически ничего плохого с вашей программой (для фактического тела функции, кроме от cut(N) -it поднимет ArithmeticError, о котором Elixir предупреждает вас во время компиляции); это совершенно правильно, он просто не делает того, что вы хотели, чтобы он делал/что вы думали.

+10

Стоит также отметить, что точно такая же проблема будет происходить от Эликсира до Эрланг. Если вы используете стандартные символы Elixir в Erlang, они будут атомами, и вы будете иметь точно такую ​​же ошибку. : D –

+0

Это замечательно! Это действительно помогает мне понять два языка. – jpsthecelt

+0

Ну, я вижу этот вопрос очень полезным для объяснения семантических и синтаксических различий в новом и захватывающем языке; особенно с точки зрения 4-строчной программы новичка, которая была, по-видимому, правильной. Мне нравится примечание Хосе, что то же самое верно в «обратном направлении». Я ценю идеи кого-либо, чтобы изменить его, чтобы быть более ясным - возможно, «семантические различия в объявлениях переменных кстати. Эликсир и Эрланг? TIA, jps – jpsthecelt

 Смежные вопросы

  • Нет связанных вопросов^_^