由买买提看人间百态

boards

本页内容为未名空间相应帖子的节选和存档,一周内的贴子最多显示50字,超过一周显示500字 访问原贴
Programming版 - 这次Scala没有入选有点意外呀
相关主题
scala和monad学FP不是为了写代码, 而是为了优秀的架构.
我对为什么使用FP的理解 (补)大牛对Scala的type system如何评价?
大牛给讲讲monad吧?Haskell这种不作不死的典型
Scala的map和flatmap什么区别?fp就是Declarative Programming
想学FP最好不要从Scala开始大家有没有觉得Scala不如Haskell美?
haskell 真是逆天, 各种特殊符号都有特殊用途为什么fp很难火
看来跳了Scala的坑是对的谁能通俗易懂地讲讲trait和monad的概念?
Haskell很难学。。Java 不是纯oo, oo 不是 imperative programming
相关话题的讨论汇总
话题: list话题: def话题: cons话题: nil话题: case
进入Programming版参与讨论
1 (共1页)
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是等价的,都用到了循环定义。

相关主题
haskell 真是逆天, 各种特殊符号都有特殊用途学FP不是为了写代码, 而是为了优秀的架构.
看来跳了Scala的坑是对的大牛对Scala的type system如何评价?
Haskell很难学。。Haskell这种不作不死的典型
进入Programming版参与讨论
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
1 (共1页)
进入Programming版参与讨论
相关主题
Java 不是纯oo, oo 不是 imperative programming想学FP最好不要从Scala开始
Learn monad in 10 minuteshaskell 真是逆天, 各种特殊符号都有特殊用途
monad就是一chaining pattern看来跳了Scala的坑是对的
aop实际上是monadHaskell很难学。。
scala和monad学FP不是为了写代码, 而是为了优秀的架构.
我对为什么使用FP的理解 (补)大牛对Scala的type system如何评价?
大牛给讲讲monad吧?Haskell这种不作不死的典型
Scala的map和flatmap什么区别?fp就是Declarative Programming
相关话题的讨论汇总
话题: list话题: def话题: cons话题: nil话题: case