发信人: wuxb (超长), 信区: FuncProgram
标 题: [合集] 看了一点Haskell语法后的感受
发信站: 水木社区 (Thu Sep 13 09:14:40 2012), 站内

☆─────────────────────────────────────☆
Sunyata (如月之恒 如日之升) 于 (Wed Aug 29 17:31:38 2012) 提到:

有人说,这个语言很数学,我就下载了点资料看了看。

感觉是这样的,不是很容易看懂,但是努力一点也能懂。

该语言我认为最数学的是[2*n| n<-[1,3,5,7],n>5]这样的结构,太亲切了。

该语言好像默认只是一元函数。比如prod x y就解释成 (prod x) 与 y的作用什么的。我一开始觉得那种函数的定义,什么Int->Int->Int怪怪的,原来是(Int->Int)->Int的意思。

但是感觉这语言似乎也不是很强大啊。总觉得它不是一种全能的语言。尽管说它比较数学,但是在真正的(计算)数学里,它没什么应用的地方吧!而且总感觉它编不出大程序来。


而且所谓的函数式语言,意味着什么呢?如果是自调用,递归,那C++也能办得到,好多计算机语言都能办得到啊。资料上说,函数式语言意味着没有副作用,变量不能变,那这么一来编起程序岂不是很不灵便?






☆─────────────────────────────────────☆
fft (止树) 于 (Wed Aug 29 17:46:10 2012) 提到:

你确定不是Int->(Int->Int)?

数学不等于计算数学,Haskell里最数学的地方在于所有类型构成一个
cartesian closed category,然后Haskell里的各种东西可以和范畴论
里的各种东西互相翻译。

【 在 Sunyata (如月之恒 如日之升) 的大作中提到: 】
: 有人说,这个语言很数学,我就下载了点资料看了看。
: 感觉是这样的,不是很容易看懂,但是努力一点也能懂。
: 该语言我认为最数学的是[2*n| n<-[1,3,5,7],n>5]这样的结构,太亲切了。
: ...................



☆─────────────────────────────────────☆
Sunyata (如月之恒 如日之升) 于 (Wed Aug 29 17:48:46 2012) 提到:

yeah!这个有意思。再看看。

【 在 fft (止树) 的大作中提到: 】
: 你确定不是Int->(Int->Int)?
: 数学不等于计算数学,Haskell里最数学的地方在于所有类型构成一个
: cartesian closed category,然后Haskell里的各种东西可以和范畴论
: ...................



☆─────────────────────────────────────☆
zahlen (zahlen) 于 (Wed Aug 29 18:34:10 2012) 提到:

这种对应更像是一个美好的梦.
不说别的, haskell的编译器敢把所有的m>>=return优化成m吗?

【 在 fft (止树) 的大作中提到: 】
: 你确定不是Int->(Int->Int)?
: 数学不等于计算数学,Haskell里最数学的地方在于所有类型构成一个
: cartesian closed category,然后Haskell里的各种东西可以和范畴论
: 里的各种东西互相翻译。




☆─────────────────────────────────────☆
fft (止树) 于 (Wed Aug 29 18:53:50 2012) 提到:

我还觉得不够美好呢,比如那搞笑的zipwith3-zipwith7 XD

【 在 zahlen (zahlen) 的大作中提到: 】
: 这种对应更像是一个美好的梦.
: 不说别的, haskell的编译器敢把所有的m>>=return优化成m吗?




☆─────────────────────────────────────☆
zahlen (zahlen) 于 (Wed Aug 29 19:00:22 2012) 提到:

zipWith7还是小意思.
见到下面这个, 我彻底无语了, 呃呃呃
data (,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,) a b c d
e f g h i j k l m n o p q r s t u v w x y z a_ b_ c_ d_ e_ f_ g_ h_ i_ j_ k
_ l_ m_ n_ o_ p_ q_ r_ s_ t_ u_ v_ w_ x_ y_ z_ a__ b__ c__ d__ e__ f__ g__ h
__ i__ j__

【 在 fft (止树) 的大作中提到: 】
: 我还觉得不够美好呢,比如那搞笑的zipwith3-zipwith7 XD




☆─────────────────────────────────────☆
fft (止树) 于 (Wed Aug 29 19:23:06 2012) 提到:

这个厉害了,哈哈哈,今年就指着这个笑话活着了 XD

【 在 zahlen (zahlen) 的大作中提到: 】
: zipWith7还是小意思.
: 见到下面这个, 我彻底无语了, 呃呃呃
: data (,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,) a b c d
: ...................



☆─────────────────────────────────────☆
vivisky (动感天空) 于 (Wed Aug 29 20:02:30 2012) 提到:

可以的,加一条优化规则就行了。

【 在 zahlen (zahlen) 的大作中提到: 】
: 这种对应更像是一个美好的梦.
: 不说别的, haskell的编译器敢把所有的m>>=return优化成m吗?




☆─────────────────────────────────────☆
zahlen (zahlen) 于 (Wed Aug 29 21:23:55 2012) 提到:

可以吗?
你怎么保证所有的moand都遵循monad laws?

【 在 vivisky (动感天空) 的大作中提到: 】
: 可以的,加一条优化规则就行了。




☆─────────────────────────────────────☆
nimi (泥股拉不二八雞) 于 (Wed Aug 29 21:53:33 2012) 提到:

為什麼不可以,如果不遵循但被定義了instance Monad那屬於程序的bug

【 在 zahlen (zahlen) 的大作中提到: 】
: 可以吗?
: 你怎么保证所有的moand都遵循monad laws?




☆─────────────────────────────────────☆
zahlen (zahlen) 于 (Wed Aug 29 22:02:07 2012) 提到:

这是Monad的定义, 我可没看到monad laws的身影
class Monad m where
(>>=) :: forall a b. m a -> (a -> m b) -> m b
(>>) :: forall a b. m a -> m b -> m b
return :: a -> m a
fail :: String -> m a
{-# INLINE (>>) #-}
m >> k = m >>= \\_ -> k
fail s = error s

monad laws纯粹靠文档和程序员的自觉来维持, 编译器想用它也得掂量掂量.

【 在 nimi (泥股拉不二八雞) 的大作中提到: 】
: 為什麼不可以,如果不遵循但被定義了instance Monad那屬於程序的bug




☆─────────────────────────────────────☆
nimi (泥股拉不二八雞) 于 (Wed Aug 29 22:06:32 2012) 提到:

本來就是應該自覺的東西。你說這個就像你拿C寫出了一個運\行就直接segfault的程序然後怪編譯器有問題一樣

【 在 zahlen (zahlen) 的大作中提到: 】
: 这是Monad的定义, 我可没看到monad laws的身影
: class Monad m where
: (>>=) :: forall a b. m a -> (a -> m b) -> m b
: ...................



☆─────────────────────────────────────☆
zahlen (zahlen) 于 (Wed Aug 29 22:33:13 2012) 提到:

看来你没明白我的话, 打个比方, 比如下面的代码
for (int i=0; i {
w = N * N;
s += w * i;
}
现代编译器都会至少优化成
w = N * N;
for (int i=0; i {
s += w * i;
}
或者直接给出 s += N * N * N * (N - 1) / 2
如果代码变成
for (int i=0; i {
s += f() * i; // f()结果与i无关
}
也许只有好的编译器才能优化.
但如果代码变成
for (int i=0; i {
s += f(g(i)) * i; // f(g(i))的结果与i无关
}
即使是最激进的编译器, 也很难在这里优化.

优化不能改变语义, 我用C写出了一个运行就直接segfault的程序, 再好的编译器绝不能
把这个segfault搞没了, 最多编译不过而已.
编译器是无法判断一个monad是否遵循了monad laws. 所以说haskell的编译器不能直接
将所有的m>>=return替换成m, 即使使用的monad都遵循了monad laws.

【 在 nimi (泥股拉不二八雞) 的大作中提到: 】
: 本來就是應該自覺的東西。你說這個就像你拿C寫出了一個運\行就直接segfault的程序然後怪編譯器有問題一樣




☆─────────────────────────────────────☆
zahlen (zahlen) 于 (Wed Aug 29 22:51:21 2012) 提到:

编译器不改变程序的语义

-- 一段糟糕的代码
data Bad a = Bad {bad :: a} deriving Show

instance Monad Bad where
m >>= f = f $ bad m
return a = Bad undefined

main = print $ Bad 1 >>= return

我本来期待的是Prelude.undefined, 编译器一优化, 成了Bad {bad = 1}.
这怎么可以?

【 在 nimi (泥股拉不二八雞) 的大作中提到: 】
: 本來就是應該自覺的東西。你說這個就像你拿C寫出了一個運\行就直接segfault的程序然後怪編譯器有問題一樣




☆─────────────────────────────────────☆
zahlen (zahlen) 于 (Thu Aug 30 06:02:53 2012) 提到:

通过Rewrite rules, ghc的确可以优化, 但毕竟是是手动的, 而且它的推倒也有限.
这点让haskell中的各种东西和数学中的各种概念对应起来的梦想更清晰一些, 可惜还是
梦想.

【 在 vivisky (动感天空) 的大作中提到: 】
: 可以的,加一条优化规则就行了。




☆─────────────────────────────────────☆
sunseraphic (この世界がいつかは幻に変わると) 于 (Thu Aug 30 23:33:11 2012) 提到:

如果你用C写出了一个会Segment Fault的编译器,再好的编译器也是检查不出来的,XD


【 在 zahlen (zahlen) 的大作中提到: 】
: 看来你没明白我的话, 打个比方, 比如下面的代码
: for (int i=0; i : {
: ...................



☆─────────────────────────────────────☆
zahlen (zahlen) 于 (Fri Aug 31 00:01:26 2012) 提到:

嗯, 我用过的编译器是查不出segfault的.
不过现在编译技术日新月异, 说不准那家做的比较智能, 也许能查出int *p = NULL;
*p = 1这样的错误呢? 所以前面我没把话说死.
编译器不改变程序的语义则不同了, 再高级的再智能也不能越俎代庖啊?

【 在 sunseraphic (この世界がいつかは幻に変わると) 的大作中提到: 】
: 如果你用C写出了一个会Segment Fault的编译器,再好的编译器也是检查不出来的,XD




☆─────────────────────────────────────☆
MingyanGuo (直学士) 于 (Fri Aug 31 03:32:25 2012) 提到:

*p = 1也未必就segfault呢,人家就蛋疼把0页也映射了你咋办。
【 在 zahlen (zahlen) 的大作中提到: 】
: 嗯, 我用过的编译器是查不出segfault的.
: 不过现在编译技术日新月异, 说不准那家做的比较智能, 也许能查出int *p = NULL;
: *p = 1这样的错误呢? 所以前面我没把话说死.
: ...................



☆─────────────────────────────────────☆
MingyanGuo (直学士) 于 (Fri Aug 31 03:34:05 2012) 提到:


【 在 zahlen (zahlen) 的大作中提到: 】
: 标 题: Re: 看了一点Haskell语法后的感受
: 发信站: 水木社区 (Wed Aug 29 22:33:13 2012), 站内
:
: 看来你没明白我的话, 打个比方, 比如下面的代码
: for (int i=0; i : {
: w = N * N;
: s += w * i;
: }
: 现代编译器都会至少优化成
: w = N * N;
: for (int i=0; i : {
: s += w * i;
: }
: 或者直接给出 s += N * N * N * (N - 1) / 2
: 如果代码变成
: for (int i=0; i : {
: s += f() * i; // f()结果与i无关
: }
: 也许只有好的编译器才能优化.
: 但如果代码变成
: for (int i=0; i : {
: s += f(g(i)) * i; // f(g(i))的结果与i无关
: }
: 即使是最激进的编译器, 也很难在这里优化.
:
: 优化不能改变语义, 我用C写出了一个运行就直接segfault的程序, 再好的编译器绝不能
: 把这个segfault搞没了, 最多编译不过而已.
: 编译器是无法判断一个monad是否遵循了monad laws. 所以说haskell的编译器不能直接
: 将所有的m>>=return替换成m, 即使使用的monad都遵循了monad laws.
haskell难道不是默认所有monad都遵守monad laws?不管实际上是不是遵守?
:
: 【 在 nimi (泥股拉不二八雞) 的大作中提到: 】
: : 本來就是應該自覺的東西。你說這個就像你拿C寫出了一個運\行就直接segfault的程序然後怪編譯器有問題一樣
:
:
: --
:
: ※ 来源:·水木社区 newsmth.net·[FROM: 114.250.223.*]




☆─────────────────────────────────────☆
zahlen (zahlen) 于 (Fri Aug 31 04:00:30 2012) 提到:

算他狠, 改成warning, 这样该行了吧, XD.

【 在 MingyanGuo (直学士) 的大作中提到: 】
: *p = 1也未必就segfault呢,人家就蛋疼把0页也映射了你咋办。




☆─────────────────────────────────────☆
zahlen (zahlen) 于 (Fri Aug 31 04:08:18 2012) 提到:

Monad laws显然不是默认的.
拿Category做个对比
class Category cat where
-- | the identity morphism
id :: cat a a
-- | morphism composition
(.) :: cat b c -> cat a b -> cat a c
{-# RULES
\"identity/left\" forall p .
id . p = p
\"identity/right\" forall p .
p . id = p
\"association\" forall p q r .
(p . q) . r = p . (q . r)
#-}

Monad则没有这样的rules.
说句题外话, 似乎rewrite rules在typeclass下不起作用. 严格地讲, 障碍可能是默认
的class op rules.

【 在 MingyanGuo (直学士) 的大作中提到: 】
: haskell难道不是默认所有monad都遵守monad laws?不管实际上是不是遵守?