p*****2 发帖数: 21240 | 1 http://www.efytimes.com/e1/fullnews.asp?edid=125719
八种最值得学习的语言
Haskell, Erlang, Clojure, OCaml都在列。Scala很不给力呀。 | c******o 发帖数: 1277 | 2 你这个搞得像电视剧里痛恨ex的怨女一样。
BTW,
我现在在自学clojure,还是觉得scala 学FP 更好,我把 scala当haskell学。
不过clojure的设计很好,很独特,我最喜欢就是lisp的data <=> code 还有 super
powerful macro,
不过注定这两个特点 strong static type 语言不能有 (会颠覆type check)。 | e*******o 发帖数: 4654 | 3 最近我也看了不少语言,我觉得 scala 和 lisp 是最值的学的。
关于haskell和scala 同意楼上,
Haskell 的难度在于怪异的syntax。
比如 Lists 的定义:
data [a] = [] | a : [a] deriving (Eq, Ord) 得半天才能看懂。
syntax 把 monad的学习的难度给增大了,或者说,syntax把monad 弄神秘了。
学 scala 的type,学起来也比较有意思。其它语言,基本用不到这些(我知道的)。 | n****1 发帖数: 1136 | 4 其他语言里面的list大多都是language primitive,因为list本来就很难用一个library
来定义。 haskell能把list分离到语言之外已经很不错了。
如果要你在scala/java/python/c++里面实现自己的list, 而且不准用array,你准备怎
么定义?
C++还好, 有template和指针, C的实现基本只能用linked list+opaque pointer.
struct List {
void* payload;
List* next;
};
这个和haskell是等价的,都用到了循环定义。
其他几个我真不知道, 你写个java/scala的看看?
【在 e*******o 的大作中提到】 : 最近我也看了不少语言,我觉得 scala 和 lisp 是最值的学的。 : 关于haskell和scala 同意楼上, : Haskell 的难度在于怪异的syntax。 : 比如 Lists 的定义: : data [a] = [] | a : [a] deriving (Eq, Ord) 得半天才能看懂。 : syntax 把 monad的学习的难度给增大了,或者说,syntax把monad 弄神秘了。 : 学 scala 的type,学起来也比较有意思。其它语言,基本用不到这些(我知道的)。
| h**d 发帖数: 5161 | 5 这上面都是非主流语言,Scala 已经和C/C++/Java/Python/JS 等等成为主流了
【在 p*****2 的大作中提到】 : http://www.efytimes.com/e1/fullnews.asp?edid=125719 : 八种最值得学习的语言 : Haskell, Erlang, Clojure, OCaml都在列。Scala很不给力呀。
| c******o 发帖数: 1277 | 6 scala的list 就是library啊。。。
我自己还练习写了一个,包括所有的functor/applicative/monad界面。
library
【在 n****1 的大作中提到】 : 其他语言里面的list大多都是language primitive,因为list本来就很难用一个library : 来定义。 haskell能把list分离到语言之外已经很不错了。 : 如果要你在scala/java/python/c++里面实现自己的list, 而且不准用array,你准备怎 : 么定义? : C++还好, 有template和指针, C的实现基本只能用linked list+opaque pointer. : struct List { : void* payload; : List* next; : }; : 这个和haskell是等价的,都用到了循环定义。
| n****1 发帖数: 1136 | 7 我的point是“data [a] = [] | a : [a] deriving (Eq, Ord)”简单明了超级易
懂, 不过是用了循环定义。
【在 c******o 的大作中提到】 : scala的list 就是library啊。。。 : 我自己还练习写了一个,包括所有的functor/applicative/monad界面。 : : library
| n****1 发帖数: 1136 | 8 我的point是“data [a] = [] | a : [a] deriving (Eq, Ord)”简单明了超级易
懂, 不过是用了循环定义。
【在 c******o 的大作中提到】 : scala的list 就是library啊。。。 : 我自己还练习写了一个,包括所有的functor/applicative/monad界面。 : : library
| c******o 发帖数: 1277 | 9 我写的和它类似,不过是没 implement eq/Ord
sealed trait List[+A]
case object Nil extends List[Nothing]
case class Cons[+A] (head: A, tail: List[A]) extends List[A]
object List {
def apply[A](as: A*): List[A] =
if (as.isEmpty) Nil
else Cons(as.head, apply(as.tail: _*))
private def asString_internal[A](l: List[A]): String =
l match {
case Nil => ""
case Cons(head,tail) => head.toString + " " + asString_internal(tail)
}
def toString[A](l: List[A]): String =
"[ " + asString_internal(l) + "]"
/////////////
def sum(ints: List[Int]): Int = ints match { // A function that uses
pattern matching to add up a list of integers
case Nil => 0 // The sum of the empty list is 0.
case Cons(x,xs) => x + sum(xs) // The sum of a list starting with `x` is
`x` plus the sum of the rest of the list.
}
def product(ds: List[Double]): Double = ds match {
case Nil => 1.0
case Cons(0.0, _) => 0.0
case Cons(x,xs) => x * product(xs)
}
def append[A](a1: List[A], a2: List[A]): List[A] =
a1 match {
case Nil => a2
case Cons(h,t) => Cons(h, append(t, a2))
}
def foldRight[A,B](l: List[A], z: B)(f: (A, B) => B): B = // Utility
functions
l match {
case Nil => z
case Cons(x, xs) => f(x, foldRight(xs, z)(f))
}
def sum_new(l: List[Int]) =
foldRight(l, 0)((x,y) => x + y)
def product_new(l: List[Double]) =
foldRight(l, 1.0)(_ * _) // `_ * _` is more concise notation for `(x,y)
=> x * y`, see sidebar
def tail[A](l: List[A]): List[A] =
l match {
case Nil => sys.error("tail of empty list")
case Cons(_,t) => t
}
def setHead[A](l: List[A])(h: A): List[A] = l match {
case Nil => sys.error("setHead on empty list")
case Cons(_,t) => Cons(h,t)
}
def drop[A](l: List[A], n: Int): List[A] =
if (n <= 0) l
else l match {
case Nil => Nil
case Cons(_,t) => drop(t, n-1)
}
def dropWhile[A](l: List[A], f: A => Boolean): List[A] =
l match {
case Cons(h,t) if f(h) => dropWhile(t, f)
case _ => l
}
def init[A](l: List[A]): List[A] =
l match {
case Nil => sys.error("init of empty list")
case Cons(_,Nil) => Nil
case Cons(h,t) => Cons(h,init(t))
}
def length[A](l: List[A]): Int =
foldRight(l, 0)((_,acc) => acc + 1)
@annotation.tailrec
def foldLeft[A,B](l: List[A], z: B)(f: (B, A) => B): B = l match {
case Nil => z
case Cons(h,t) => foldLeft(t, f(z,h))(f)
}
def sum2(l: List[Int]) = foldLeft(l, 0)(_ + _)
def product2(l: List[Double]) = foldLeft(l, 1.0)(_ * _)
def reverse[A](l: List[A]): List[A] = foldLeft(l, List[A]())((acc,h) =>
Cons(h,acc))
def foldRightViaFoldLeft[A,B](l: List[A], z: B)(f: (A,B) => B): B =
foldLeft(reverse(l), z)((b,a) => f(a,b))
def concat[A](l: List[List[A]]): List[A] =
foldRight(l, Nil:List[A])(append)
def map_origin[A, B](la: List[A])(f: A => B): List[B] =
foldRight(la, Nil:List[B])((h,t) => Cons(f(h), t))
////
def unit[A](a: A): List[A] =
Cons(a, Nil)
def flatMap[A, B](la: List[A])(f: A => List[B]): List[B] =
concat(foldRight(la, Nil:List[List[B]])((h,t) => Cons(f(h),t)))
def join[A](lla: List[List[A]]): List[A] =
flatMap(lla)(la => la)
def compose[A,B,C](f: A => List[B], g: B => List[C]): A => List[C] =
a => flatMap(f(a))(g)
def apply[A,B](la: List[A])(f: List[A => B]): List[B] =
flatMap(f)(t1 => flatMap(la)(t2 => unit(t1(t2))))
def map2[A,B,C](la: List[A], lb: List[B])(f: (A, B) => C): List[C] =
apply(lb)(apply(la)(unit(f.curried)))
def map[A, B](la: List[A])(f: A => B): List[B] =
apply(la)(unit(f))
def fold[A](l: List[A])(z: A)(op: (A, A) ⇒ A): A =
foldRight(l, z)(op)
def filter[A](l: List[A])(f: A => Boolean): List[A] =
foldRight(l, Nil:List[A])((h,t) => if (f(h)) Cons(h,t) else t)
}
【在 n****1 的大作中提到】 : 我的point是“data [a] = [] | a : [a] deriving (Eq, Ord)”简单明了超级易 : 懂, 不过是用了循环定义。
| p**o 发帖数: 3409 | 10 用类就行了。java和python都类似。
class Node (object):
""" Node for a linked list. """
def __init__ (self, value, next=None):
self.value = value
self.next = next
class LinkedList (object):
""" Linked list ADT implementation using class.
A linked list is a wrapper of a head pointer
that references either None, or a node that contains
a reference to a linked list.
"""
def __init__ (self, iterable=()):
self.head = None
for x in iterable:
self.head = Node(x, self.head)
def __iter__ (self):
p = self.head
while p: # not None
yield p.value
p = p.next
def prepend (self, x): # 'appendleft'
self.head = Node(x, self.head)
def reverse (self):
""" In-place reversal. """
p = self.head
self.head = None
while p: # not None
p0 = p
p = p.next
p0.next = self.head
self.head = p0
if __name__ == '__main__':
ll = LinkedList([6,5,4])
ll.prepend(3); ll.prepend(2)
print list(ll)
ll.reverse()
print list(ll)
library
【在 n****1 的大作中提到】 : 其他语言里面的list大多都是language primitive,因为list本来就很难用一个library : 来定义。 haskell能把list分离到语言之外已经很不错了。 : 如果要你在scala/java/python/c++里面实现自己的list, 而且不准用array,你准备怎 : 么定义? : C++还好, 有template和指针, C的实现基本只能用linked list+opaque pointer. : struct List { : void* payload; : List* next; : }; : 这个和haskell是等价的,都用到了循环定义。
| | | c******o 发帖数: 1277 | 11 他说的其实不在点上,关键是第一要immutable, no variable,第二是recursion, no
loop
你再试试看。
【在 p**o 的大作中提到】 : 用类就行了。java和python都类似。 : class Node (object): : """ Node for a linked list. """ : def __init__ (self, value, next=None): : self.value = value : self.next = next : class LinkedList (object): : """ Linked list ADT implementation using class. : A linked list is a wrapper of a head pointer : that references either None, or a node that contains
| n****1 发帖数: 1136 | 12 这个就是OO开始恶心人的地方了。 在这个阶段就把所有与List有关的函数都绑在一
起了,那用户要加新的有关函数, 不就得subclass或者做delegation?
我觉得实现List核心不在于你写的那串很长的成员函数, 而在于List的trait。 也就
是说把List变成MonadPlus. 这个只需要定义foldr, fmap与join, mzero, mplus就可以
了。
foldr:: (a->b->b)-> b -> [a] -> b
foldr f seed [] = seed
foldr f seed x:xs = f x (foldr f seed xs)
fmap:: (a-> m b) -> m a -> m b
fmap f li = foldr ((:).f) [] li
join:: (m (m a) )-> m a
join li = foldr ++ [] li
mzero = []
mplus = ++
++ la lb = foldr (:) lb la
【在 c******o 的大作中提到】 : 我写的和它类似,不过是没 implement eq/Ord : sealed trait List[+A] : case object Nil extends List[Nothing] : case class Cons[+A] (head: A, tail: List[A]) extends List[A] : object List { : def apply[A](as: A*): List[A] = : if (as.isEmpty) Nil : else Cons(as.head, apply(as.tail: _*)) : private def asString_internal[A](l: List[A]): String = : l match {
| c******o 发帖数: 1277 | 13 你没看懂我的,我的就是这样,只不过没有把trait 拿出来。。。
再给你贴一个我的练习。
trait Functor[F[_]] {
def map[A,B](t: F[A])(f: A => B): F[B]
}
trait Applicative[F[_]] extends Functor[F]{
def unit[A](a: => A): F[A]
def ap[A,B](fa: F[A])(fab: F[A => B]): F[B]
override def map[A,B](t: F[A])(f: A => B): F[B] = ap(t)(unit(f))
}
trait Monad[F[_]] extends Applicative[F] {
def unit[A](a: => A): F[A]
def flatMap[A,B](ma: F[A])(f: A => F[B]): F[B]
override def ap[A,B](la: F[A])(f: F[A => B]): F[B] =
flatMap(f)(t1 => flatMap(la)(t2 => unit(t1(t2))))
override def map[A,B](ma: F[A])(f: A => B): F[B] =
flatMap(ma)(a => unit(f(a)))
}
import scala.language.higherKinds
val OptionApplicatable = new Applicative[Option] {
def unit[A](a: => A) = Some(a)
def ap[A,B](a: Option[A])(f: Option[A => B]): Option[B] =
f.flatMap {
t1 => a.flatMap {
t2 => unit(t1(t2))
}
}
}
val OptionMonad = new Monad[Option] {
def unit[A](a: => A) = Some(a)
def flatMap[A,B](a: Option[A])(f: A => Option[B]): Option[B] =
a.flatMap(f)
}
【在 n****1 的大作中提到】 : 这个就是OO开始恶心人的地方了。 在这个阶段就把所有与List有关的函数都绑在一 : 起了,那用户要加新的有关函数, 不就得subclass或者做delegation? : 我觉得实现List核心不在于你写的那串很长的成员函数, 而在于List的trait。 也就 : 是说把List变成MonadPlus. 这个只需要定义foldr, fmap与join, mzero, mplus就可以 : 了。 : foldr:: (a->b->b)-> b -> [a] -> b : foldr f seed [] = seed : foldr f seed x:xs = f x (foldr f seed xs) : fmap:: (a-> m b) -> m a -> m b : fmap f li = foldr ((:).f) [] li
| n****1 发帖数: 1136 | 14 有点奇怪, monad是functor/applicative的一种。 应该是你定义好monad, 就不用定
义functor/applicative了吧。 Monad也只需要fmap和join啊。
没学过scala, 不懂
val OptionApplicatable = new Applicative[Option]
是干啥的, 能解释下么?
【在 c******o 的大作中提到】 : 你没看懂我的,我的就是这样,只不过没有把trait 拿出来。。。 : 再给你贴一个我的练习。 : trait Functor[F[_]] { : def map[A,B](t: F[A])(f: A => B): F[B] : } : trait Applicative[F[_]] extends Functor[F]{ : def unit[A](a: => A): F[A] : def ap[A,B](fa: F[A])(fab: F[A => B]): F[B] : override def map[A,B](t: F[A])(f: A => B): F[B] = ap(t)(unit(f)) : }
| c******o 发帖数: 1277 | 15 我定义了一个option monad (也是applicative)
定义了一个applicative (不是monad)
这一行就是定义一个type是 applicative 里面的type是Option.
你当然可以再用它来做一个OptionApplicative instance
see, OO has nothing bad with FP, it just Imperative against FP
【在 n****1 的大作中提到】 : 有点奇怪, monad是functor/applicative的一种。 应该是你定义好monad, 就不用定 : 义functor/applicative了吧。 Monad也只需要fmap和join啊。 : 没学过scala, 不懂 : val OptionApplicatable = new Applicative[Option] : 是干啥的, 能解释下么?
| c******o 发帖数: 1277 | 16 in scala, type, type constructor, type classes are all kind of trait/class,
just with generics.
scala is almost as powerful as Haskell, just not pure | n****1 发帖数: 1136 | 17 I think in an immutable world, the main disagreement over OOP is on the
modularity of libraries/functions, agree? OOP in FP just pack some functions
together in a class. While haskell just preserves a flat structure, and
provide modularity on file level.
I think trait is similar to typeclass in haskell. There is no class in
haskell.
,
【在 c******o 的大作中提到】 : in scala, type, type constructor, type classes are all kind of trait/class, : just with generics. : scala is almost as powerful as Haskell, just not pure
| d****i 发帖数: 4809 | 18 看到Scala的Nil,就想到了肯定来自于Lisp的nil, 说实话还是喜欢C/C++/Java的NULL(
null)。数学上面的术语都是用null的,比如null space, null set, null hypothesis
等等,scala用nil的大概是受了lisp的影响,C系的和其他主流语言都是用NULL。
【在 c******o 的大作中提到】 : 我写的和它类似,不过是没 implement eq/Ord : sealed trait List[+A] : case object Nil extends List[Nothing] : case class Cons[+A] (head: A, tail: List[A]) extends List[A] : object List { : def apply[A](as: A*): List[A] = : if (as.isEmpty) Nil : else Cons(as.head, apply(as.tail: _*)) : private def asString_internal[A](l: List[A]): String = : l match {
| n****1 发帖数: 1136 | 19 还真不是, nil是针对object的, null是针对pointer/reference的. 参加Objective-
C(nil null都有。)
NULL(
hypothesis
【在 d****i 的大作中提到】 : 看到Scala的Nil,就想到了肯定来自于Lisp的nil, 说实话还是喜欢C/C++/Java的NULL( : null)。数学上面的术语都是用null的,比如null space, null set, null hypothesis : 等等,scala用nil的大概是受了lisp的影响,C系的和其他主流语言都是用NULL。
| d****i 发帖数: 4809 | 20 obj-C不清楚,C++里面没有NULL引用,只能是NULL指针。不过貌似obj-C的nil本质上就
是NULL:
http://stackoverflow.com/questions/4283690/objective-c-whats-th
Objective-
【在 n****1 的大作中提到】 : 还真不是, nil是针对object的, null是针对pointer/reference的. 参加Objective- : C(nil null都有。) : : NULL( : hypothesis
| e*******o 发帖数: 4654 | 21 我的意思haskell的list 定义难看懂。
haskell 的优先级,$符号, 我也是搞了好久才明白。
可能我太笨,也可能这是haskell 流行不了的原因。
当然了,你可以说你会了就简单了...
library | n****1 发帖数: 1136 | 22 我学的语言中感觉Lisp最难读懂, 比如下面的call/cc例子, 我花了十几天才想明白
。 俺觉得觉得相对lisp来说, Haskell已经很标准易读了。
(define the-continuation #f)
(define (test)
(let ((i 0))
; call/cc calls its first function argument, passing
; a continuation variable representing this point in
; the program as the argument to that function.
;
; In this case, the function argument assigns that
; continuation to the variable the-continuation.
;
(call/cc (lambda (k) (set! the-continuation k)))
;
; The next time the-continuation is called, we start here.
(set! i (+ i 1))
i))
> (test)
1
> (the-continuation)
2
> (the-continuation)
3
> ; stores the current continuation (which will print 4 next) away
> (define another-continuation the-continuation)
> (test) ; resets the-continuation
1
> (the-continuation)
2
> (another-continuation) ; uses the previously stored continuation
4 |
|