Skip to content

Instantly share code, notes, and snippets.

View monzou's full-sized avatar

Takuro Monji monzou

  • Tokyo
View GitHub Profile
@monzou
monzou / rpn.hs
Created June 30, 2012 07:01
逆ポーランド記法電卓
solveRPN :: String -> Double
-- solveRPN expression = head (fold foldingFunction [] (words expression)) をポインタフリースタイルで書いた ↓
solveRPN = head . foldl foldingFunction [] . words
where
-- foldingFunction stack operator
-- stack は x:y:ys に分割し, x と y を operator で評価してスタックの先頭を置き換える
foldingFunction (x:y:ys) "*" = (y * x):ys
foldingFunction (x:y:ys) "+" = (y + x):ys
foldingFunction (x:y:ys) "-" = (y - x):ys
foldingFunction (x:y:ys) "/" = (y / x):ys
import Control.Applicative
-- <$> は fmap の中置関数
main = print $ filter (>50) $ (*) <$> [2, 5, 10] <*> [ 8, 10, 11 ] -- [ 55, 80, 100, 110 ]
import Control.Applicative
-- fmap : (a -> b) -> f a -> f b
-- fmap は関数とファクター値を引数にとって, 関数をファンクター値の中の値に適用
class Functor f where
fmap :: (a -> b) -> f a -> f b
-- <*> : f (a -> b) -> f a -> f b (f is Fanctor)
-- <*> は関数の入っているファンクター値と値の入っているファンクター値を引数にとって, ひとつ目のファンクターの中身の関数をふたつ目のファンクターの中身に適用
-- タプルの第一要素に fmap したいが, Functor は型引数を 1 つしか取れないので newtype を定義する
newtype Pair b a = Pair { getPair :: (a, b) } deriving (Show)
instance Functor (Pair c) where
fmap f (Pair (x, y)) = Pair (f x, y)
main = print $ fmap reverse(Pair ("foo", "bar")) -- Pair ("oof", "bar")
@monzou
monzou / type.hs
Created July 7, 2012 07:36
type, newtype, data の違い
import Data.Monoid
-- type, newtype, data の違い
-- type : 型に別名を付けるもの
type IntList = [Int]
-- newtype : 型クラスのインスタンスを作りやすくするために既存の型を包んで新しい型をつくるもの
-- newtype は値コンストラクタとフィールドが 1 つだけという制限の付いた data 宣言だと見なしても良い。
-- 既存の型をある型クラスのインスタンスにしたい場合に使う。
newtype CharList = CharList { getCharList :: [Char] }
import Data.Monoid
-- モノイドが便利なのはどんな場合?
-- 例えばふたつの文字列を引数に取り, その長さを比較して Ordering を返す。
-- 但し長さが等しい場合は文字列を辞書比較して返す。という関数を作りたい場合。
-- ふつうにつくるとこうなる
lengthCompare1 :: String -> String -> Ordering
lengthCompare1 x y = let
a = length x `compare` length y
-- モナドは強化されたアプリカティブファンクタ−。
-- アプリカティブファンクターは文脈の付いた値に, 文脈を保ったまま普通の関数を適用させてくれる。
-- ただの 1 という値を文脈を持った Just 1 にしたりする関数は pure, 文脈を持った値に関数を適用するのが <*>
<*> :: (Applicative f) => f (a -> b) -> f a -> f b
(*) <$> Just 2 <*> Just 8 -- ((*) Just 2) -> Just 8
-- モナドは普通の値 a をとって文脈付きの値を返す関数に, 文脈付きの値 m a を渡すときに用いる。
import Control.Monad.State
--
-- 普通に Stack
--
type Stack = [Int]
pop :: Stack -> (Int, Stack)
pop (x:xs) = (x, xs)
import Data.List
import Control.Monad
readMaybe :: (Read a) => String -> Maybe a
readMaybe st = case reads st of [(x, "")] -> Just x
_ -> Nothing
foldingFunction :: [Double] -> String -> Maybe [Double]
foldingFunction (x:y:ys) "*" = return ((y * x):ys)
foldingFunction (x:y:ys) "+" = return ((y + x):ys)
import Data.Ratio
import Data.List
import Control.Monad
--
-- 非決定性計算をしたい場合にモナドを使うと良い感じ
--
newtype Prob a = Prob { getProb :: [(a, Rational)] } deriving Show -- (3, 1%2) = 50 % の確率の 3
instance Functor Prob where