Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Erlang 如何为单字母ASCII字符串(值0-127)键入规范?_Erlang_Elixir_Dialyzer - Fatal编程技术网

Erlang 如何为单字母ASCII字符串(值0-127)键入规范?

Erlang 如何为单字母ASCII字符串(值0-127)键入规范?,erlang,elixir,dialyzer,Erlang,Elixir,Dialyzer,同样地,如何为“单个”UTF8字符指定typespec 在类型定义中,我可以使用泛型“any string”或“any utf8 string” 有什么方法可以将typespec转换成这样的位模式吗?仅基于二进制的事实。即使你们可以定义这样的规格,我也不相信透析器足够复杂,可以在这样的匹配中发现故障。您只需要在运行时使用保护和模式匹配来实现此类行为,如: def unicode?(<<0::size(1), a::size(7)>>), do: true def unic

同样地,如何为“单个”UTF8字符指定typespec

在类型定义中,我可以使用泛型“any string”或“any utf8 string”

有什么方法可以将typespec转换成这样的位模式吗?

仅基于二进制的事实。即使你们可以定义这样的规格,我也不相信透析器足够复杂,可以在这样的匹配中发现故障。您只需要在运行时使用保护和模式匹配来实现此类行为,如:

def unicode?(<<0::size(1), a::size(7)>>), do: true
def unicode?(<<6::3, _::5, 2::2, _::6>>), do: true 
def unicode?(<<14::4, _::4, 2::2, _::6, 2::2, _::6>>), do: true
def unicode?(<<30::5, _::3, 2::2, _::6, 2::2, _::6, 2::2, _::6>>), do: true
def unicode?(str) when is_binary(str), do: false

我要在这个问题上加上Erlang标签(还有透析器标签),因为我认为这更多的是透析器的问题,而不是长生不老药的问题。我认为这是不可能的。我最好的猜测是指定一个范围
0..127::8
,但我认为它不会起作用。根据我在透析器文档中看到的情况,似乎
char()
类型规范最接近您想要的,但仍然允许0..255(而不仅仅是0..127范围)。@OnorioCatenacci。我真的很想匹配一个“单个”UTF8码点,它可以从8位到32位,有特定的位模式,所以char()不行。好的,我们可能还需要更多的上下文来确定为什么一个简单的验证函数,可以使用模式匹配,我们知道它是有效的,不能满足您的目的。如何才能类型规格这一个utf8字符有助于类型检查你正在执行?据我所知,Erlang和Elixir编译器不会观察到类型不匹配(除了您提供的编译错误之外),因此我假设类型检查用于您自己的内部检查。
@type tile :: <<0::1, _::7>>
@type tile :: <<0::1, _::7>> | 
              <<6::3, _::5, 2::2, _::6>> | 
              <<14::4, _::4, 2::2, _::6, 2::2, _::6>> |
              <<30::5, _::3, 2::2, _::6, 2::2, _::6, 2::2, _::6>>
<<14::4, _::4, 2::2, _::6, 2::2, _::6>> = "○"
== Compilation error in file lib/board.ex ==
** (ArgumentError) argument error
    (elixir) lib/kernel/typespec.ex:1000: Kernel.Typespec.typespec/3
    (elixir) lib/kernel/typespec.ex:1127: anonymous fn/4 in Kernel.Typespec.typespec/3
    (elixir) lib/enum.ex:1899: Enum."-reduce/3-lists^foldl/2-0-"/3
    (elixir) lib/kernel/typespec.ex:1127: Kernel.Typespec.typespec/3
    (elixir) lib/kernel/typespec.ex:828: anonymous fn/4 in Kernel.Typespec.typespec/3
    (elixir) lib/enum.ex:1899: Enum."-reduce/3-lists^foldl/2-0-"/3
    (elixir) lib/kernel/typespec.ex:828: Kernel.Typespec.typespec/3
    (elixir) lib/kernel/typespec.ex:470: Kernel.Typespec.translate_type/3
def unicode?(<<0::size(1), a::size(7)>>), do: true
def unicode?(<<6::3, _::5, 2::2, _::6>>), do: true 
def unicode?(<<14::4, _::4, 2::2, _::6, 2::2, _::6>>), do: true
def unicode?(<<30::5, _::3, 2::2, _::6, 2::2, _::6, 2::2, _::6>>), do: true
def unicode?(str) when is_binary(str), do: false
defguardp is_valid_utf_part(code) when code in 0b10000000..0b10111111

defguard is_unicode(<<ascii>>) when ascii in 0b0000000..0b01111111
defguard is_unicode(<<first, second>>)
  when first in 0b11000000..0b11011111
   and is_valid_utf_part(second)
defguard is_unicode(<<first, second, third>>)
  when first in 0b11100000..0b11101111
   and is_valid_utf_part(second)
   and is_valid_utf_part(third)
defguard is_unicode(<<first, second, third, fourth>>)
  when first in 0b11110000..0b11110111
   and is_valid_utf_part(second)
   and is_valid_utf_part(third)
   and is_valid_utf_part(fourth)