morris555's diary

高校生のブログです。

fromEnumについて

Twitterで流れてきたこれを見て、あれ?と思ったので調べてみました

fromEnum???

数字ならその数字を、文字なら、文字コードを返すらしい。

ghciで調べてみる

Prelude> :t fromEnum 
fromEnum :: Enum a => a -> Int

なるほど

列挙型ならいいのか

というわけで、ちょっと試しに

Prelude> data Num = Zero | One | Two | Three | Four | Five | Six | Seven | Eight | Nine | Ten deriving (Enum , Show)
Prelude> fromEnum One 
1
Prelude> fromEnum Nine
9

この場合はインデックスを返すらしい(?)

という事は

Prelude> :i Bool 
data Bool = False | True        -- Defined in `GHC.Types'

Prelude> fromEnum (1==1)
1
Prelude> fromEnum (1==2)
0

これだけの事だったのか。

ちなみに…

数列表記も列挙型ならいいらしいので

Prelude> data Num = Zero | One | Two | Three | Four | Five | Six | Seven | Eight | Nine | Ten deriving (Enum , Show)
Prelude> [Zero .. Ten]
[Zero,One,Two,Three,Four,Five,Six,Seven,Eight,Nine,Ten]
Prelude> [Zero, Two ..]
[Zero,Two,Four,Six,Eight,Ten]

こんなことも出来ちゃうみたいです。

Arch LinuxにXmonad入れた

メインで使ってるマシンにXmonadいれました。

なぜか最近Ubuntuが不安定だったのでこのタイミングでArch Linuxに変えました。

Arch Linuxのインストールはnetinstall版を使いたかったのですが、何故か有線より無線を優先して認識してしまったのでCoreの方を使いました。

インストールは適当に…

Xmonadも基本的にはXmonad - ArchWikiに書いてあるので普通にできました。

簡単ですね。

まとめ

Arch Linux使おう

Xmonad使おう

テスト勉強しよう

FFIを使ってみよう

FFIを使ってHaskellからC++の関数を呼び出してみました。

まずC++のコード

#include <iostream>

extern "C" {

void hello() {
  std::cout << "Hello World!" << std::endl;
}

}

大切なのは「extern "C" {}」を忘れないことです。

そしてHaskell

{-# LANGUAGE ForeignFunctionInterface #-}

main = c_hello

foreign import ccall "hello" c_hello :: IO ()

こんな感じです

あとは、

$ g++ -c hello.cpp
$ ghc -lstdc++ --make main.hs hello.o

これでOKです。

$ ./main
Hello World!

こんな感じに出来ます。

情報によるとghcが64bitコードに対応してないらしい(?)ので

g++に-m32オプションをつけて下さい。

Problem 22

Problem 22です。

import Data.List
import Data.Maybe
import Control.Applicative

score = sum . map (fromMaybe 0 . flip lookup (zip ['A'..'Z'] [1..26]))

main = do
  names <- (sort . list) <$> getContents
  print . (foldr (\(x, y) s -> s + x * y) 0) . zip [1..] $ map score names
    where
      list x = read $ "[" ++ x ++ "]"
# ./p22 < name.txt

こんな感じです。

Problem 21

Problem 21です。

import Data.List

main = print . sum . filter isAmicable $ [1..10000]

isAmicable n = n == (sumDivisors . sumDivisors $ n) && n /= sumDivisors n

sumDivisors n = sum . filter (\x -> (n `mod` x) == 0) $ [1..n-1]

遅いです。

Problem 19

今回は、Problem 19です。

import Data.Time.Calendar
import Data.Time.Calendar.WeekDate

main = print . length $ [d | d <- [fromGregorian y m 1 | y <- [1901..2000], m <- [1..12]], let (_, _, w) = toWeekDate d, w == 7]

Haskellなら簡単でした。