我有这段代码,我只是在没有必要进行任何错误处理的测试用例中使用它.它的作用是:
代码如下:
def parseDs(ins: List[String]) = {
def filterResults[U, T](in: List[Either[U, T]]): List[T] = {
in.filter(y => y.isRight).map(z => z.right.get)
}
filterResults(ins.map(x => DSJsonMapper.parseDSResult(x)))
}
Run Code Online (Sandbox Code Playgroud)
现在,我还没有做过很多多态函数,但这很有效.不过我觉得它有点难看.有没有人有更好的建议,如何完成同样的事情.
我知道这将归结为个人偏好的情况.但欢迎提出建议.
Benjamin C. Pierce 在其类型和编程语言一书的第23.8节中写道:
系统F的另一个充分研究的限制是由Leivant(1983)引入的rank-2多态性 [...].当类型被绘制为树时,如果没有从其根到∀量词的路径传递到2个或更多箭头的左侧,则称类型为等级2.[...]在rank-2系统中,所有类型都被限制为等级2.这个系统比prenex(ML)片段稍强一些,因为它可以为更多无类型的lambda术语分配类型.
Kfoury和Tiuryn(1990)证明了系统F的秩-2片段的类型重建的复杂性与ML的相同(即,DExptime-complete).Kfoury和Wells(1999)给出了秩2系统的第一个正确的类型重建算法,并且表明系统F的等级3和更高的类型重建是不可判定的.
因此,知道秩-2多态的类型推断是可判定的,并且自1999年以来就已知算法.Haskell支持其RankNTypes语言扩展,但它支持rank-n多态.
哪些语言(如果有的话)实现了rank-2参数多态而不是System F?
由于类型推断是可判定的并且没有最差的复杂性,为什么既没有SML也没有OCaml扩展多态性到-2级?
为什么我们没有在野外看到和阅读更多关于rank-2多态性的信息?
我有一个Haskell项目,该项目非常密集地使用fmap数据结构。为了避免一次又一次遍历相同的数据结构,同时保留自由使用的可能性,我决定使用-type来保护一些较大的结构。fmapCoyoneda
Coyoneda类型具有构造函数Coyoneda :: (x -> y) -> f x -> Coyoneda f y。这个想法是通过参数化,更确切地说是通过共同Yooneda引理,类型f a和Coyoneda f a是同构的,但是Coyoneda类型的优点是它延迟了实际的结构遍历。
例如,在下面的代码中,第一个表达式遍历基础结构3次,而第二个表达式仅遍历一次:
fmap k $ fmap h $ fmap g $ (x :: f a)
lowerCoyoneda $ fmap k $ fmap h $ fmap g $ liftCoyoneda $ (x :: f a)
Run Code Online (Sandbox Code Playgroud)
实际上,第二行减少如下:
lowerCoyoneda $ fmap k $ fmap h $ fmap g $ liftCoyoneda $ x
lowerCoyoneda $ fmap k …Run Code Online (Sandbox Code Playgroud) Normally in Perl 6, only roles are allowed to be parametric. Here, we'll be attempting to make classes, a kind (referred to from here on out as a metaobject) that isn't normally allowed to be parametric, parametric.
If you try to make a class parametric the naive way, this happens:
bastille% perl6 -e 'class Foo[::T] {}'
===SORRY!=== Error while compiling -e
Unable to parse class definition
at -e:1
------> class Foo?[::T] {}
expecting any of:
generic role
Run Code Online (Sandbox Code Playgroud)
But if you …
我有一个结构NotificationOption和另一个结构NotificationOption2以及From<NotificationOption>for的实现NotificationOption2。
我想转换Vec<NotificationOption>为Vec<NotificationOption2>:
struct NotificationOption {
key: String,
}
struct NotificationOption2 {
key: String,
}
impl From<NotificationOption> for NotificationOption2 {
fn from(n: NotificationOption) -> Self {
Self {
key: n.key,
}
}
}
let options: Vec<NotificationOption> = ...;
let options2: Vec<NotificationOption2> = options.into();
Run Code Online (Sandbox Code Playgroud)
但我收到编译器错误:
struct NotificationOption {
key: String,
}
struct NotificationOption2 {
key: String,
}
impl From<NotificationOption> for NotificationOption2 {
fn from(n: NotificationOption) -> Self {
Self { …Run Code Online (Sandbox Code Playgroud) AsRef 文档写入
用于进行廉价的引用到引用转换。
我明白reference-to-reference部分是什么意思cheap?我希望它与复杂性理论(大哦,等等)“便宜”无关。
例子:
struct User {
email: String,
age: u8,
}
impl AsRef<User> for User {
fn as_ref(&self) -> &User {
&self
}
}
fn main() {
let user = User { email: String::from("myemail@example.com"), age: 25 };
let user_ref = &user;
//...
}
Run Code Online (Sandbox Code Playgroud)
什么是执行的原因AsRef为User,如果我可以随便拿一个参考&user?执行的规则是AsRef什么?
PS:我在其他论坛和文档中找不到任何可以回答这些问题的内容。
我正在创建一个回合制游戏。我想定义一个数据类型,从许多可能的类型中编码一种类型。这是一个励志的例子:
我已经Turn使用 GADT定义了一个类型,所以每个值的类型都Turn a说明了它的值。
data Travel
data Attack
data Flee
data Quit
data Turn a where
Travel :: Location -> Turn Travel
Attack :: Int -> Turn Attack
Flee :: Turn Flee
Quit :: Turn Quit
Run Code Online (Sandbox Code Playgroud)
现在我可以写出这样的类型decideTravel :: GameState -> Turn Travel,非常有表现力而且很好。
当我想返回多种可能的转弯类型之一时,就会出现问题。我想编写类似于以下的函数:
-- OneOf taking two types
decideFightingTurn :: GameState -> OneOf (Turn Attack) (Turn Flee)
-- OneOf takes three types
decideTurn :: GameState -> OneOf (Turn Attack) (Turn Travel) (Turn Quit)
Run Code Online (Sandbox Code Playgroud)
此 …
在显式类型注释的情况下,Haskell检查推断类型是否至少与其签名一样多态,或者换句话说,推断类型是否是显式类型的子类型.因此,以下功能是错误的:
foo :: a -> b
foo x = x
bar :: (a -> b) -> a -> c
bar f x = f x
Run Code Online (Sandbox Code Playgroud)
然而,在我的场景中,我只有一个函数签名,需要验证它是否被潜在的实现"居住" - 希望这个解释完全有意义!
由于parametricity财产我认为两者foo并bar没有不存在的实现,因此,两者都应该被拒绝.但我不知道如何以编程方式结束.
目标是整理所有或至少一部分无效类型签名,如上所述.我很感激每一个提示.
我正在编写一个用于在Perl 6中创建monad的库。由于仅使用常规参数角色就无法正确扩展monad(据我所知),因此我决定创建一个自定义元模型类,该类扩展Metamodel::ParametricRoleHOW并引入特殊语法来创建单子。问题是当我尝试写时monad MonadName[::T],会发生这种情况:
bastille% perl6 monad-test.p6
===SORRY!=== Error while compiling /home/morfent/Documents/p6-Monad/monad-test.p6
Unable to parse monad definition
at /home/morfent/Documents/p6-Monad/monad-test.p6:8
------> monad Identity?[::T] {
expecting any of:
generic role
Run Code Online (Sandbox Code Playgroud)
当我只写monad Identity { ... }时,尝试专门化类型时会抛出该错误。我该怎么写,使单子参数化?单子不具备准确扩展角色元模型,但我宁愿它是可以使用does与单子,而不是is。另外,即使我已经知道如何执行此操作,其他人也可能没有,因为我认为它没有记录在案,因此,如果您可以在回答中包括如何使任何类型的参数成为一般参数,那么这将是一个更好的参考。
这是我目前用于创建monad的代码:
use v6.d;
class Type::MonadHOW is Metamodel::ParametricRoleHOW {
has Int $!feature_flags;
my enum FeatureFlags (
Value => 0x1,
Bind => 0x2,
Then => 0x4,
Return => 0x8
);
method !set_value(\M, Attribute:D $attr) {
self.Metamodel::ParametricRoleHOW::add_attribute: M, $attr; …Run Code Online (Sandbox Code Playgroud) 我将使用很棒的库https://tpolecat.github.io/doobie/,它功能齐全。
我正在经历第一个例子,我已经认识到:
Transactor 是一种数据类型,它知道如何连接到数据库、分发连接并清理它们;有了这些知识,它可以转换
ConnectionIO ~> IO,这给了我们一个可以运行的程序。
ConnectionIO ~> IO 是范畴论中的自然变换,但从未完全理解,究竟什么是自然变换。
但是,我知道这是从一类到另一类的转变。例如:
F[A] ~> G[A]
Run Code Online (Sandbox Code Playgroud)
是从类别F到G不改变内容的自然转变。
并非一切都可以自然转化,问题是,library doobie 的作者怎么知道,他可以从 进行自然转化ConnectionIO ~> IO?
haskell functional-programming scala category-theory parametric-polymorphism