小编rec*_*nja的帖子

为什么Haskell缺少"明显的"类型类

考虑面向对象的语言:

大多数人来自面向对象的编程背景,熟悉各种语言中常见且直观的界面,这些界面捕获了Java CollectionList界面的本质.Collection"对象"是指不一定具有自然排序/索引的对象集合.A List是具有自然排序/索引的集合.这些接口在Java中抽象了许多库数据结构,其他语言中的等效接口也是如此,并且需要对这些接口有深入的了解才能有效地与大多数库数据结构一起工作.

过渡到Haskell:

Haskell有一个类型级系统,它类似于对象上的接口作用于类型.当类型考虑功能时,Haskell似乎有一个关于Functors,Applicative,Monads等的设计良好的类型层次结构.他们显然想要正确且抽象良好的类型类.然而,当你看很多Haskell的容器(List,Map,Sequence,Set,Vector)他们几乎都具有非常相似(或相同)的功能,但通过类型类不是抽象的.

一些例子:

  • null 用于测试"空虚"
  • length/size用于元素计数
  • elem/member用于设置包含
  • empty 和/或 singleton默认构造
  • union 为集合联盟
  • (\\)/diff用于设定差异
  • (!)/(!!)用于不安全的索引(部分功能)
  • (!?)/lookup用于安全索引(总功能)

如果我想使用上面的任何函数,但是我已经导入了两个或更多个容器,我必须从导入的模块中开始隐藏函数,或者只从模块中显式导入必要的函数,或者限定导入的模块.但由于所有功能都提供相同的逻辑功能,因此它似乎很麻烦.如果函数是从类型类定义的,而不是在每个模块中单独定义的,那么编译器的类型推理机制可以解决这个问题.只要它们共享类型类,它也会使底层容器切换变得简单(即:让我们只使用一个Sequence而不是List更好的随机访问效率).

为什么Haskell没有Collection和/或Indexable类型类来统一和概括其中的一些功能?

haskell abstraction standard-library typeclass

54
推荐指数
7
解决办法
4043
查看次数

在haskell中定义一个新的monad不会引发Applicative的实例

我试图定义一个新的monad,我得到一个奇怪的错误

newmonad.hs

newtype Wrapped a = Wrap {unwrap :: a}
instance Monad Wrapped where
  (>>=) (Wrap x) f =  f x
  return x = Wrap x

main = do
  putStrLn "yay"
$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.10.1

$ ghc newmonad.hs 
[1 of 1] Compiling Main             ( newmonad.hs, newmonad.o )

newmonad.hs:2:10:
    No instance for (Applicative Wrapped)
      arising from the superclasses of an instance declaration
    In the instance declaration for ‘Monad Wrapped’

为什么我需要定义一个实例Applicative

monads haskell

53
推荐指数
1
解决办法
7192
查看次数

阶乘时间算法O(n!)的示例

我正在研究学校的时间复杂度,我们的主要关注点似乎是多项式时间 O(n^c)算法和准线性时间 O(nlog(n))算法,偶尔的指数时间 O(c^n)算法作为运行时透视的一个例子.然而,从未涉及处理更大的时间复杂性.

我想看一个在阶乘时间内 运行的算法解决方案的示例问题O(n!).该算法可能是一种解决问题的简单方法,但不能人为膨胀以在因子时间运行.

如果因子时间算法是解决问题的最着名的算法,则额外的街道信誉.

algorithm complexity-theory factorial time-complexity

35
推荐指数
4
解决办法
4万
查看次数

将Parsec与Data.Text一起使用

使用Parsec 3.1,可以解析几种类型的输入:

  • [Char]Text.Parsec.String
  • Data.ByteStringText.Parsec.ByteString
  • Data.ByteString.LazyText.Parsec.ByteString.Lazy

我没有看到该Data.Text模块的任何内容.我想解析Unicode内容而不会遇到String效率低下的问题.所以我基于Text.Parsec.ByteString模块创建了以下模块:

{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}

module Text.Parsec.Text
    ( Parser, GenParser
    ) where

import Text.Parsec.Prim

import qualified Data.Text as T

instance (Monad m) => Stream T.Text m Char where
    uncons = return . T.uncons

type Parser = Parsec T.Text ()
type GenParser t st = Parsec T.Text st
Run Code Online (Sandbox Code Playgroud)
  1. 这样做有意义吗?
  2. 它与Parsec API的其余部分兼容吗?

附加评论:

我必须{-# LANGUAGE NoMonomorphismRestriction #-} …

haskell parsec

33
推荐指数
3
解决办法
4504
查看次数

Haskell程序的基本结构

我看过的许多Haskell教程几乎完全集中在语法上,而对如何构建程序的报道却很少.

例如...

这是C++应用程序的简要概述:

#include <iostream>
using namespace std;

int addition (int a, int b)
{
  int r;
  r=a+b;
  return (r);
}

int main ()
{
  int z;
  z = addition (5,3);
  cout << "The result is " << z;
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我第一次开始学习C++时,这些例子极大地帮助我学习如何将各个部分组合成工作程序.也许我正在寻找错误的地方,但我找不到任何像Haskell那样直接和简单的例子.

我已经知道很多Haskell语法.我可以编写递归列表推导,并操纵字符串,整数和列出wazoo.

简而言之:我只想知道Haskell中两个子例程和变量传递是什么样的.如果我能够对如何构造Haskell程序有一些基本的了解,我可能最终能够将我学到的所有语法都用于某些用途.

haskell function subroutine data-structures

30
推荐指数
1
解决办法
6134
查看次数

Haskell程序输出`<< loop >>`

我写了一个Haskell程序,它在列表上执行二进制搜索.至少这就是我的想法.当我用程序编译程序ghc v7.6.3并运行程序时,我得到了以下输出:

progname: <<loop>>
Run Code Online (Sandbox Code Playgroud)

这个输出究竟意味着什么?这是否意味着我有一个无限循环ghc优化了?我该怎么调试呢?

debugging haskell compilation ghc haskell-platform

27
推荐指数
1
解决办法
5358
查看次数

组成两个函数是什么意思?

Haskell Typeclassopedia 3.2节的练习5要求在声明中提供证据或反例

两个Functors的组合也是一个Functor.

我一开始以为这是在讨论组合fmap由两个单独的a实例定义的方法Functor,但这并没有多大意义,因为就我所知,类型不会匹配.对于两种类型,f并且f',类型fmap将是fmap :: (a -> b) -> f a -> f bfmap :: (a -> b) -> f' a -> f' b,并且实际上看起来并不可组合.那么组成两个是什么意思Functors呢?

theory haskell functor

26
推荐指数
4
解决办法
3648
查看次数

Haskell列表的内部表示?

哈斯克尔支持一些基本的操作,通过列表递归,比如head,tail,initlast.我在内部想知道Haskell如何表示其列表数据?如果它是单链表,那么随着列表的增长init,last操作可能会变得昂贵.如果它是一个双向链表,那么所有四个操作都可以O(1)很容易地完成,尽管会以一些内存为代价.无论哪种方式,对我来说都很重要,所以我可以编写适当的代码.(尽管,函数式编程的精神似乎是"问它是做什么,而不是它是怎么做的").

haskell list data-structures

19
推荐指数
2
解决办法
1721
查看次数

Functor实例是唯一的吗?

我想知道FunctorHaskell中的实例在多大程度上由函子定律(唯一)确定.

由于ghc可以Functor为至少"普通"数据类型派生实例,因此它们似乎必须至少在各种情况下都是唯一的.

为方便起见,Functor定义和函子定律是:

class Functor f where
  fmap :: (a -> b) -> f a -> f b

fmap id = id
fmap (g . h) = (fmap g) . (fmap h)
Run Code Online (Sandbox Code Playgroud)

问题:

  • 可以map从假设它是一个Functor实例开始得出定义data List a = Nil | Cons a (List a)吗?如果是这样,为了做到这一点,必须做出哪些假设?

  • 是否有任何Haskell数据类型具有多个Functor满足函子定律的实例?

  • 什么时候可以ghc派生出一个functor实例而什么时候不能呢?

  • 所有这些都取决于我们如何定义平等吗?该Functor法律在价值的平等的条件下表达,但我们不要求FunctorsEq实例.那么这里有一些选择吗?

关于相等性,肯定存在一种我称之为"构造函数相等"的概念,它允许我们推断任何类型的任何值[a,a,a]都"等于",即使它没有为它定义.所有其他(有用的)平等概念可能比这种等价关系更粗糙.但我怀疑法律中的平等更多是"推理平等"关系,并且可以是特定于应用的.有什么想法吗?[a,a,a]aa(==)Functor

haskell functor ghc

19
推荐指数
1
解决办法
1355
查看次数

Test.QuickCheck.Monadic:为什么断言应用于Bool,而不是Testable a => a

使用QuickCheck测试Monadic代码时(Claessen,Hughes 2002),assert有类型:

assert :: (Monad m, Testable a) => a -> PropertyM m ()
Run Code Online (Sandbox Code Playgroud)

但是,在Test.QuickCheck.Monadic,它有类型:

assert :: (Monad m) => Bool -> PropertyM m ()
Run Code Online (Sandbox Code Playgroud)

为什么assert在库中有后一种类型?

haskell quickcheck

18
推荐指数
1
解决办法
338
查看次数