很少有几次我在学习“高级” Haskell时看到(->)
。
当我尝试运行ghci
时:t (->)
失败,以为有时甚至官方文档也使用此符号。
据我所能猜测,(->)
是 Hask 中的任何形态,基本上是任何Haskell函数。我认为这个想法是要修复源端点或目标端点:例如,((->) Int)
可能意味着Int
类型的任何功能;显然,(Int (->))
表示Int
中的任何功能。
下一个假设是(->)
可能是一个终结者。 fmap
的实现似乎是微不足道的:拥有类型a
和态射f :: a -> b
的固定端点,可以产生((->) b)
的实例。它保留id
,但不会撕裂现有的构图:即fmap(g . f) = fmap(g) . fmap(f)
。
所以我的第一个问题是:我对吗?
我的第二个问题是为什么:t (->)
在ghci
中失败了?
我的第三个问题,有什么方法可以在真实的Haskell代码中使用(->)
?我需要启用一些{{ #Pragma ...
扩展名吗?还是仅仅是用来解释概念的理论概念?
最后,最后一个问题。是否存在双重概念(<-)
?
答案 0 :(得分:6)
->
是函数类型的类型构造函数。 f :: A -> B
表示“ f
是从某种类型A
到某种类型B
的函数”。
:t (->)
是一个错误,因为->
不是值,并且没有类型。它是一个类型(或更确切地说是类型构造函数)。同样,:t Maybe
和:t Int
是错误。
与普通运算符一样,中缀应用程序是(咖喱)前缀应用程序的语法糖;即x + y
可以写成(+) x y
或((+) x) y
,A -> B
也可以写成(->) A B
或((->) A) B
。
((->) Int)
并不意味着“ Int
类型的任何功能”;它是 from Int
函数的类型构造函数。它本身不是有效的类型,但是您可以将其应用于类型以获得有效的函数类型。例如((->) Int) String
是从Int
到String
的功能类型。
(Int (->))
是一种错误;会尝试将Int
应用于(->)
,但是Int
不会接受任何参数。
(->) e
实际上是任何类型Functor
(具有e
,即函数组成)的fmap = (.)
。也是Applicative
和Monad
(相当于Reader
)。
所有这些都是标准的Haskell语法。不需要语言扩展。
<-
在类型级别上不存在。它是保留的语法,可以在表达式中使用,例如在列表理解([ x * 2 | x <- [0 ..] ]
)或do
块(do { x <- p; return (x * 2) }
)中;它也用在其他一些上下文中,但没有用在类型中。