单变量在Haskell中的应用
我最近开始学习Haskell,并遇到了一个关于单变量在Haskell中的应用,haskell,Haskell,我最近开始学习Haskell,并遇到了一个关于Applicative的问题 我需要为你做一个实现 newtype MyTriple a = MyTriple (a,a,a) deriving Show 作为应用程序实例 我真的不明白我到底该怎么做。据我所知,applicative主要用于多个变量。在这个特殊的例子中,我不确定带有符号的部分应该是什么。 有人能给我解释一下吗(是否基于我的例子)? 如果可能的话,请不要直接回答。我假设您对纯没有问题 您可以在GHCi中使用MyTriple和,以更好
Applicative
的问题
我需要为你做一个实现
newtype MyTriple a = MyTriple (a,a,a) deriving Show
作为应用程序
实例
我真的不明白我到底该怎么做。据我所知,applicative主要用于多个变量。在这个特殊的例子中,我不确定带有
符号的部分应该是什么。
有人能给我解释一下吗(是否基于我的例子)?
如果可能的话,请不要直接回答。我假设您对
纯
没有问题
您可以在GHCi中使用MyTriple
和
,以更好地了解您应该做什么。例如,如果您将返回类型限制为MyTriple\ucode>,则可以询问
的类型:
*Q65326400> :t (<*>) :: _ -> _ -> MyTriple _
<interactive>:1:10: error:
* Found type wildcard `_' standing for `MyTriple (a1 -> w1)'
Where: `a1', `w1' are rigid type variables bound by
the inferred type of
<expression> :: MyTriple (a1 -> w1) -> MyTriple a1 -> MyTriple w1
at <interactive>:1:10-29
To use the inferred type, enable PartialTypeSignatures
* In an expression type signature: _ -> _ -> MyTriple _
In the expression: (<*>) :: _ -> _ -> MyTriple _
...
或者,如果我们转换为更“友好”的类型变量:
MyTriple (a -> b) -> MyTriple a -> MyTriple b
因此,正如@Nearoo在评论中指出的那样,
的左侧应该是一个MyTriple
值,它包含a->b
类型的函数。这可以是三个不同的函数,但它们必须具有兼容的类型
右侧应该是aMyTriple a
,返回值aMyTriple b
例如,您可以实现一个行为如下的Applicative
实例:
*Q65326400> MyTriple (null, odd . length, elem 'f') <*> MyTriple ("foo", "bar", "baz")
MyTriple (False,True,False)
*Q65326400>MyTriple(空,奇。长,元素f')MyTriple(“foo”,“bar”,“baz”)
MyTriple(假、真、假)
左侧是MyTriple(String->Bool)
值,右侧是MyTriple字符串
这不是唯一可能的Applicative
实例。我可以很容易地想到更多的例子,但它们可能并不都是合法的
下一步,一旦你弄明白了如何实现一个实例,就是说服你自己(可能还有其他人)这个实例遵守这个规则。这将排除一些技术上可能的实例。我将假设您对纯
没有问题
您可以在GHCi中使用MyTriple
和
,以更好地了解您应该做什么。例如,如果您将返回类型限制为MyTriple\ucode>,则可以询问
的类型:
*Q65326400> :t (<*>) :: _ -> _ -> MyTriple _
<interactive>:1:10: error:
* Found type wildcard `_' standing for `MyTriple (a1 -> w1)'
Where: `a1', `w1' are rigid type variables bound by
the inferred type of
<expression> :: MyTriple (a1 -> w1) -> MyTriple a1 -> MyTriple w1
at <interactive>:1:10-29
To use the inferred type, enable PartialTypeSignatures
* In an expression type signature: _ -> _ -> MyTriple _
In the expression: (<*>) :: _ -> _ -> MyTriple _
...
或者,如果我们转换为更“友好”的类型变量:
MyTriple (a -> b) -> MyTriple a -> MyTriple b
因此,正如@Nearoo在评论中指出的那样,
的左侧应该是一个MyTriple
值,它包含a->b
类型的函数。这可以是三个不同的函数,但它们必须具有兼容的类型
右侧应该是aMyTriple a
,返回值aMyTriple b
例如,您可以实现一个行为如下的Applicative
实例:
*Q65326400> MyTriple (null, odd . length, elem 'f') <*> MyTriple ("foo", "bar", "baz")
MyTriple (False,True,False)
*Q65326400>MyTriple(空,奇。长,元素f')MyTriple(“foo”,“bar”,“baz”)
MyTriple(假、真、假)
左侧是MyTriple(String->Bool)
值,右侧是MyTriple字符串
这不是唯一可能的Applicative
实例。我可以很容易地想到更多的例子,但它们可能并不都是合法的
下一步,一旦你弄明白了如何实现一个实例,就是说服你自己(可能还有其他人)这个实例遵守这个规则。这就排除了一些技术上可能出现的情况。我认为应该用liftA2
而不是()
<代码>()
是应用程序的提升功能
(<*>) = liftA2 ($)
给定长度(向量)的列表与函数同构
Vec 0 a = (Void -> a)
Vec 1 a = (() -> a)
Vec 2 a = (Bool -> a)
Vec 3 a = (Fin3 -> a)
..
Vec n a = (Fin n -> a)
它们的应用实例遵循元素级函数定义。诸如MyTriple
和其他同构于函数(..->)
的函子被调用
使用相同的应用程序实例验证(>)Fin3
与V3
/MyTriple
同构
考虑使用($)
实例化(·)
时会发生什么
你可以通过
如果不是因为“角色”问题,我们将导出分配的,也就是说,我们不能在函子f
的参数下强制,我认为是从liftA2
而不是()
的角度<代码>()
是应用程序的提升功能
(<*>) = liftA2 ($)
给定长度(向量)的列表与函数同构
Vec 0 a = (Void -> a)
Vec 1 a = (() -> a)
Vec 2 a = (Bool -> a)
Vec 3 a = (Fin3 -> a)
..
Vec n a = (Fin n -> a)
它们的应用实例遵循元素级函数定义。诸如MyTriple
和其他同构于函数(..->)
的函子被调用
使用相同的应用程序实例验证(>)Fin3
与V3
/MyTriple
同构
考虑使用($)
实例化(·)
时会发生什么
你可以通过
如果不是因为“角色”问题,即我们不能在函子f
的参数下强制,那么我们就可以导出分布式的
,在Haskell中编写类型类的实例时,有两件事可以指导我们正确实现:类型和类型类法则
类型说明了什么?
Haskell(以及其他一些函数式语言)中使用的类型系统的一个显著特性是给定了一个足够多态的函数
类型,实现它的方法出人意料地少。直觉是
由于多态函数对其操作的类型一无所知,
它不能对这些类型的值应用任何有趣的操作
最简单的例子是a->a
类型的函数。它必须产生价值
类型a
作为其
pure x = MyTriple (x, x, x)
MyTriple (f, g, h) <*> MyTriple (x, y, z) = ...
-- f, g, h :: a -> b
-- x, y, z :: a
MyTriple (f1, f2, f3) <*> MyTriple (x1, x1, x3) = MyTriple (fi xp, fj xq, fk xr)
MyTriple (x1, x1, x3) = MyTriple (id xp, id xq, id xr) = MyTriple (xp, xq, xr)
MyTriple (f1, f2, f3) <*> MyTriple (x1, x1, x3) = MyTriple (fi x1, fj x2, fk x3)
MyTriple (f1, f2, f3) <*> pure x = MyTriple (fi x, fj x, fk x)
pure ($x) <*> MyTriple (f1, f2, f3) = MyTriple (fp x, fq x, fr x)
MyTriple (fi x, fj x, fk x) = MyTriple (fp x, fq x, fr x)
MyTriple (f1, f2, f3) <*> MyTriple (x1, x1, x3) = MyTriple (f1 x1, f2 x2, f3 x3)