我应该如何阅读这种类型的语法?
How should I read this type syntax?
我正在通读 Type-Driven Development with Idris,我 运行 在尝试使用页面上的 valToString
函数时遇到了一些令人困惑的格式23.具体我加了个函数洞:
valToString : (x : Bool) -> StringOrInt x -> String
valToString x val = (?f val)
当我向 REPL 询问这个洞的类型时,这是打印的结果:
*Hello> :t f
x : Bool
val : case x of
True => Int
False => String
--------------------------------------
f : case x of True => Int False => String -> String
Holes: Main.f
val
的类型在这里已经足够可读了,但是我应该如何阅读f
的类型呢?书中提到 on page 19 空格在 Idris 中很重要;如果我将它用于我的程序中的类型,这是否是有效语法?
看来这与空格无关。只是格式错误。
这个
f : case x of True => Int False => String -> String
可以这样重新格式化:
f : (case x of {True => Int; False => String}) -> String
当我在 Idris repl 中键入 :t f
时,我会看到接下来的内容:
*Hello> :t f
x : Bool
val : StringOrInt x
--------------------------------------
f : StringOrInt x -> String
Holes: Main.f
这种情况只是类型 StringOrInt x
的内联版本。虽然格式很差。可能写这章的时候用的是老版本的Idris
。
更新(2017 年 7 月 23 日)
不幸的是,不是每个人都有书 :( 我试图猜测 StringOrInt
的类型,但我没有准确地猜到它。我在我的代码中使用了下一个定义:
StringOrInt : Bool -> Type
StringOrInt True = Int
StringOrInt False = String
根据这个定义,我从上面得到了输出。而实际上 StringOrInt
以下一种方式定义:
StringOrInt : Bool -> Type
StringOrInt x = case x of
True => Int
False => String
这两个定义在语义上是等价的。区别仅在于句法。但显然这会导致 :t f
命令的编译器输出不同。
我打开了对应的issue:
我正在通读 Type-Driven Development with Idris,我 运行 在尝试使用页面上的 valToString
函数时遇到了一些令人困惑的格式23.具体我加了个函数洞:
valToString : (x : Bool) -> StringOrInt x -> String
valToString x val = (?f val)
当我向 REPL 询问这个洞的类型时,这是打印的结果:
*Hello> :t f
x : Bool
val : case x of
True => Int
False => String
--------------------------------------
f : case x of True => Int False => String -> String
Holes: Main.f
val
的类型在这里已经足够可读了,但是我应该如何阅读f
的类型呢?书中提到 on page 19 空格在 Idris 中很重要;如果我将它用于我的程序中的类型,这是否是有效语法?
看来这与空格无关。只是格式错误。
这个
f : case x of True => Int False => String -> String
可以这样重新格式化:
f : (case x of {True => Int; False => String}) -> String
当我在 Idris repl 中键入 :t f
时,我会看到接下来的内容:
*Hello> :t f
x : Bool
val : StringOrInt x
--------------------------------------
f : StringOrInt x -> String
Holes: Main.f
这种情况只是类型 StringOrInt x
的内联版本。虽然格式很差。可能写这章的时候用的是老版本的Idris
。
更新(2017 年 7 月 23 日)
不幸的是,不是每个人都有书 :( 我试图猜测 StringOrInt
的类型,但我没有准确地猜到它。我在我的代码中使用了下一个定义:
StringOrInt : Bool -> Type
StringOrInt True = Int
StringOrInt False = String
根据这个定义,我从上面得到了输出。而实际上 StringOrInt
以下一种方式定义:
StringOrInt : Bool -> Type
StringOrInt x = case x of
True => Int
False => String
这两个定义在语义上是等价的。区别仅在于句法。但显然这会导致 :t f
命令的编译器输出不同。
我打开了对应的issue: