ringtaroのHaskell日記

2010年02月07日(日)

プログラミングHaskell第4章練習問題をやったよ。 22:51

1.


halve :: [a] -> ([a], [a])
halve xs = ( take cnt xs, drop cnt xs )
    where
        cnt = length xs `div` 2

2.


-- 2.a
safetail_a :: [a] -> [a]
safetail_a xs = if (null xs) then []
                             else drop 1 xs

-- 2.b
safetail_b :: [a] -> [a]
safetail_b xs | null xs   = []
              | otherwise = drop 1 xs

-- 2.c
safetail_c :: [a] -> [a]
safetail_c []     = []
safetail_c (x:xs) = xs

3.


(v) :: Bool -> Bool -> Bool
True  v True  = True
True  v False = True
False v True  = True
False v False = False

(v) :: Bool -> Bool -> Bool
False v False = False
_     v _     = True

(v) :: Bool -> Bool -> Bool
False v b  = b
_  v _     = True

(v) :: Bool -> Bool -> Bool
b v c | b == c    = b
      | otherwise = b

4.


and1 :: Bool -> Bool -> Bool
and1 x y = if (x == True) then
               if (y == True) then True
                              else False
           else
               False

5.


and2 :: Bool -> Bool -> Bool
and2 x y = if (x == True) then y
                          else False

6.


mult = ¥x -> ¥y -> ¥z -> x*y*z

2010年01月26日(火)

プログラミングHaskell第1章練習問題をやったよ。 19:05

1.

  double (double 2)
= double (2 + 2)
= double 2 + double 2
= 4 + 4
= 8

正直何をさせたいのかよくわからなかったが、「どんな順番で計算をやっても結局解答は一緒になるよ」ということを確かめさせる問題だったらしい。


2.

  sum[x]
= x + sum[]
= x + 0
= x

簡単な証明問題ですね。

3.

myproduct [] = 1
myproduct (x:xs) = x * product xs

  product [2,3,4]
= 2 * product [3,4]
= 2 * 3 * product [4]
= 2 * 3 * 4 * product []
= 2 * 3 * 4 * 1
= 24

計算問題。

プログラミングの勉強で計算問題って珍しいよね。

4.

rqsort [] = []
rqsort (x:xs) = rqsort larger ++ [x] ++ rqsort smaller
  where
    smaller = [a | a <- xs, a <= x]
    larger  = [b | b <- xs, b >  x]

qsortのlargerとsmallerを入れ替えればOK。


5.

同地が1つにまとまる。

nqsort [] = []
nqsort (x:xs) = nqsort smaller ++ [x] ++ nqsort larger
  where
    smaller = [a | a <- xs, a < x]
    larger  = [b | b <- xs, b > x]
nqsort [2,2,3,1,1] = [1,2,3]

プログラミングHaskell第2章練習問題をやったよ。 19:18

1.

(2^3)*4
(2*3)+(4*5)
2+(3*(4^5)))

2.実行したよ。

3.

n = a `div` length xs
  where
    a = 10
    xs = [1,2,3,4,5]

・関数名にNは使えないのでnに変更。

・整数の除算演算子は'div'ではなく、`div`。

・a=10のインデント位置を修正。

4.

last1 xs = xs !! (length xs - 1)

last2 xs = head (reverse xs )

5.

init1 xs = take (length xs - 1) xs

init2 xs = reverse (tail (reverse xs))

プログラミングHaskell第3章練習問題をやったよ。 20:08

1.

['a','b','c'] :: [Char]
('a','b','c') :: (Char, Char, Char)
[(False,'o'),(True,'1')] :: [(Bool, Char)]
([False,True],['0','1']) :: ([Bool], [Char])
[tail,init,reverse] :: [[a] -> [a]]

2.

second :: [a] -> a
swap :: (t, t1) -> (t1, t)
pair :: t -> t1 -> (t, t1)
double :: (Num a) => a -> a
palindrome :: (Eq a) => [a] -> Bool
twice :: (t -> t) -> t -> t

3.確かめた。

4.

よくわからなかったので、解答をそのまま訳してみた。

In general, 
checking if two functions are equal requires enumerating all possible argument values, 
and checking if the functions give the same result for each of these values. 
For functions with a very large (or infinite) number of argument values, such as values of type Int or Integer, 
this is not feasible. 
However, 
for small numbers of argument values, such as values of type of type Bool , 
it is feasible.

一般的に、
2つの関数が等しいかどうかをチェックするには、すべてのとりうる引数の値を列挙し、
かつ、その2つの関数がこれら引数それぞれに対して同じ値を与えることをチェックすること
を必要とする
IntやInteger型のように、大変多くの(または無限の)引数値を持つ関数にとって
これは不可能である。
しかしながら、
Bool型のように、少ない引数値ならば
可能である。

つまり、2つの関数が等しいかを調べるには、取りうる引数すべてに対して、結果が同じかを調べなきゃならない。

てことはIntみたいに取りうる値がほぼ無限の型が引数になってる関数は、結果が同じであるかを調べるのにどえらい時間がかかる。

だから一般的には無理。

でも、取りうる引数のすべてが少ないBoolが引数になっている関数だったら、全ての引数に対して結果が同じ可動化を比較することができる。

よって、2つの関数が等しいかを調べることができるので、Eqインスタンスにすることができる。

ってことだよな。

SultanSultan2013/07/27 02:10That's more than sebilnse! That's a great post!

MonyMony2013/07/28 09:19Furrealz? That's <a href="http://cxxyedpxlu.com">marlslouevy</a> good to know.

JordyJordy2013/07/28 17:11You've hit the ball out the park! Inciedrble! http://ihocbuqlc.com [url=http://gnhqrzkf.com]gnhqrzkf[/url] [link=http://sxlswxtrqh.com]sxlswxtrqh[/link]

KimKim2013/07/30 21:21I hate my life but at least this makes it <a href="http://awofnoevyb.com">bealabre.</a>

2007年03月15日(木)

ゆるーいHaskell[9] を見た 18:02

今回は型システムの話。どうやら型システムは憶えていた模様。

しかし、flipというものが出てくる。

Prelude> :m Data.Tree
Prelude Data.Tree> let t = Node 1 [Node 2 [Node 3 [], Node 4 []], Node 5 []]
Prelude Data.Tree> rootLabel $ flip (!!) 1 $ subForest $ flip (!!) 0 $ subForest t
4

ぬ、何だこれは?

調べると、引数の順番を入れ替えてくれるものらしい。

ほほう、これは便利。

でも、何故ここで登場?

Prelude Data.Tree> rootLabel $ (subForest $ subForest t !! 0) !! 1
4

で、良いのでは?と思ったけど、

Prelude Data.Tree> let getSubForestItem = \i n -> flip (!!) i $ subForest n
Prelude Data.Tree> rootLabel $ getSubForestItem 1 $ getSubForestItem 0 t
4

と、こんな風に考えたのかなと勝手に解釈&勝手に納得。