-- pipe.hs
import System.Process
import System.Environment
main :: IO ()
a:_ <- getArgs
(_, Just so, _, _) <- createProcess (proc "runghc" ["randomList.hs",a]) { std_out = CreatePipe }
_ <- createProcess (proc "/home/i/myPlayer/viewer" []) { std_in = UseHandle so }
return ()
-- randomList.hs
import System.Random
import System.Process
import System.Posix.Time (epochTime)
import System.Environment
import System.Directory
import System.FilePath.Posix
imnum = 10
lines' = return . lines
randomize :: [FilePath] -> IO [FilePath]
randomize lst = do
let c = length lst
r <- fromEnum <$> epochTime >>= (\x -> return (randomRs (0, (c-1)) (mkStdGen x) ))
return [lst !! x|x <- take imnum r]
dirFilePairs :: [FilePath] -> IO [(FilePath,FilePath)]
dirFilePairs lst = return [(takeDirectory x,x) | x <- lst]
fileFilePairs :: [(FilePath,FilePath)] -> IO [(FilePath,FilePath)]
fileFilePairs = mapM (\(a,b) -> do{aa <- getAA a; return (aa,b)})
where
getAA p = do
fs <- listDirectory p >>= filtFile ".jpg"
if fs == [] then return "cd.jpg"
else return $ p ++ ['/'] ++ head(fs)
filtFile ex = return . filter (\x -> takeExtension x == ex)
main = do
fs <- getArgs >>= \(a:_) -> readFile a
lines' fs >>= randomize >>= dirFilePairs >>= fileFilePairs >>= print
1,1 全て
-- viewer.hs
import Graphics.UI.Gtk
import System.Process
import MyButton
iSize = 100
getAps :: IO [(FilePath,FilePath)]
getAps = getContents >>= return . read
func1 f = createProcess (proc "audacious" [f]) >> return ()
main = do
aps <- getAps
initGUI
w <- windowNew
set w [windowWindowPosition := WinPosNone,
windowDefaultWidth := 400, windowDefaultHeight := 900]
vb <- vBoxNew False 0
sw <- scrolledWindowNew Nothing Nothing
scrolledWindowAddWithViewport sw vb
containerAdd w sw
bs <- mapM (\(a,b) -> newImgButton iSize (a,b) func1) aps
mapM (containerAdd vb) bs
widgetShowAll w
w `on` unrealize $ mainQuit
mainGUI
~
-- MyButton.hs
module MyButton where
import Graphics.UI.Gtk
newImgButton size (f,f') func = do
p <- pixbufNewFromFileAtSize f size size
i <- imageNewFromPixbuf p
b <- buttonNew
set b [buttonImage := i]
l <- labelNew $ Just $ drop 12 f'
set l [labelWrap := True]
hb <- hBoxNew False 0
containerAdd hb b
containerAdd hb l
b `on` buttonActivated $ func f'
return hb
晴れときどきHaskell
2025年4月7日月曜日
myPlayer
2020年5月23日土曜日
Haskell Process
Haskellの System.Processは便利ですが、問題もあります。
単一スレッドでの逐次処理を保証していない。(想像です。)
次のようなスクリプトを書いてみた。
--a.hs
main = print [1..10]
--t.hs
import System.Process
loop x = createProcess (proc "runghc" ["a.hs"]) >> return ()
main = mapM_ loop [1..100]
単一スレッドでの逐次処理を保証していない。(想像です。)
次のようなスクリプトを書いてみた。
--a.hs
main = print [1..10]
--t.hs
import System.Process
loop x = createProcess (proc "runghc" ["a.hs"]) >> return ()
main = mapM_ loop [1..100]
実行結果。
$ runghc t.hs
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,[1,2,3,4,5,6,7,8,9,1[1,2,3,4,5,6,7,8,9,10]
5,6,7,8,9,10]
0]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,[1,2,3,4,5,6,7,8,9,10]
,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10[1,2,3,4[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4[1,2,3,4,5,6,7,8,9,10]
i@i:~/haskell$ [1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,,[1,2,3,4,5,6,7,8,9,10]
5,6,7,8,9,10]
]
[1,2,3,4,5,6,7,8,9,10]
,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3[1,2,3,4,5,6,7,8,9,10,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
,[1,2,3,4,5,6,7,8,9,10]
5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
]
[1,2,3,4,5,6,[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[[1,2,3,4,5,6,7,8,9,10]
1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,1[1,2,3,4,5,6,7,8,9,10]
7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
0[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
]
[1,2,3,4,5,6,7,8,9,10]
[[1,2,3,4,5,6,7,8,9,10]
1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8[1,2,3,4[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,,,5,6,[7,8,19,1,02]
,3,4,5,6,7,8,9,10]
9,10]
[1,2,3,4,5,6,7,8,9,10]
5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9,10]
[1..10]のリストを書き終える前に次のリストを書き始めている。
100回のLoop の途中で t.hs スクリプトを終了している。
深い意味は僕には不明ですが、実用プログラムで使う場合には注意が必要なのでは・・・。
2019年2月13日水曜日
セル・オートマトン
ソースコードは下記アドレス
一部Repaを使ってみました。
以下のインストール が必要。
$ cabal update -v
$ cabal install repa -v
$ cabal -v install repa-io
$ cabal install parallel -v
コンパイルは
$ ghc -O2 -threaded -rtsopts --make -XFlexibleContexts -eventlog cellA.hs
作成された実行ファイルを実行します。
$ ./cellA 110 +RTS -N2 -l
ルールはコマンドライン引数で与えます。
eventlog が作成されます。
$ threadscope cellA.eventlog
一応2コアで動いています。
ルール110の実行例。
$ display a.bmp
ルール225
2018年12月3日月曜日
Github リポジトリにファイルを追加
2018年11月2日金曜日
Module ‘System.Cmd’ is deprecated
--b.hs
import System.Cmd
main = rawSystem "ls" ["-lh"]
$ runghc b.hs
b.hs:1:1: Warning:
Module ‘System.Cmd’ is deprecated: Use "System.Process" instead
import System.Process
main = createProcess (proc"ls" ["-lh"])
import System.Cmd
main = rawSystem "ls" ["-lh"]
$ runghc b.hs
b.hs:1:1: Warning:
Module ‘System.Cmd’ is deprecated: Use "System.Process" instead
import System.Process
main = createProcess (proc"ls" ["-lh"])
2018年6月21日木曜日
複素数
Pythonは複素数を直接書くことができます。
Python 2.7.12 (default, Dec 4 2017, 14:50:18)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> a=0+1j
>>> a
1j
>>> b=d
>>> b
1.4142135623730951
>>> d=abs(a-b)
>>> d
1.7320508075688774
Prelude> :l r.hs
[1 of 1] Compiling Main ( r.hs, interpreted )
Ok, modules loaded: Main.
*Main> map r [0..9]
[0.0,1.0,1.4142135623730951,1.7320508075688774,2.0,2.23606797749979,2.4494897427831783,2.6457513110645907,2.8284271247461903,3.0000000000000004]
容易に想像できると思いますがNが大きくなると時間がかかるようになります。
*Main> :set +s
*Main> r 1000000
1000.0000000000299
(7.74 secs, 1,673,363,512 bytes)
このような再帰は fold で置き換えることができます。
Python 2.7.12 (default, Dec 4 2017, 14:50:18)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> a=0+1j
>>> a
1j
実数部が0のとき省略できます。
>>> a=1j
>>> a
1j
虚数部が0のときこれも省略できます。
>>> b=1
>>> b
1
これはただの実数ですが複素数と組み合わせるとちゃんと複素数の計算をしてくれます。
>>> a-b
(-1+1j)
複素数は距離の計算をとても楽にしてくれます。
a,b 2点間の距離は差をとって絶対値を計算すればよい。
>>> d=abs(a-b)
>>> d
1.4142135623730951
これは√2です。
これをbに代入します。
>>> b=d
>>> b
1.4142135623730951
>>> d=abs(a-b)
>>> d
1.7320508075688774
これは√3です。
このように計算結果を次々に代入していけば全ての整数の平方根がもとめられます。
(複素数の計算の内部で sqrt を使っているのでは? というツッコミはあると思いますが無視してください)
Haskellではこのような記法はできません。
Data.Complex モジュールの
(:+)
というコンストラクターで複素数のインスタンスをつくります。
Haskellではコンストラクターは関数であり、(:+)は演算子として定義されているので次のようにします。
GHCi, version 7.10.3: http://www.haskell.org/ghc/ :? for help
Prelude> import Data.Complex
Prelude Data.Complex> let a=0:+1
Prelude Data.Complex> a
0 :+ 1
Prelude Data.Complex> let b=1:+0
Prelude Data.Complex> b
1 :+ 0
ちょっと不格好ですが・・・
ちょっと不格好ですが・・・
Haskell は、複素数の絶対値を複素数で返します。
Prelude Data.Complex> abs(a-b)
1.4142135623730951 :+ 0.0
これは abs が
abs :: Num a => a -> a
と定義されているからです。
かわりにmagnitudeをつかいます。
Prelude Data.Complex> :t magnitude
magnitude :: RealFloat a => Complex a -> a
Prelude Data.Complex> magnitude(a-b)
1.4142135623730951
N−1 の平方根がわかれば N の平方根が計算できることから再帰的に定義できます。
--r.hs
import Data.Complex
dist a b = magnitude (a-b)
a = 0 :+ 1
r 0 = 0
r n = dist a b
where b = r (n-1) :+ 0
Prelude> :l r.hs
[1 of 1] Compiling Main ( r.hs, interpreted )
Ok, modules loaded: Main.
*Main> map r [0..9]
[0.0,1.0,1.4142135623730951,1.7320508075688774,2.0,2.23606797749979,2.4494897427831783,2.6457513110645907,2.8284271247461903,3.0000000000000004]
容易に想像できると思いますがNが大きくなると時間がかかるようになります。
*Main> :set +s
*Main> r 1000000
1000.0000000000299
(7.74 secs, 1,673,363,512 bytes)
このような再帰は fold で置き換えることができます。
*Main> let r' n = foldl (\x _ -> dist a (x :+ 0)) 0 [1..n]
*Main> r' 1000000
1000.0000000000299
(5.28 secs, 1,474,441,216 bytes)
さらに Data.List モジュールの foldl' を使うと
*Main> import Data.List
*Main Data.List> let r'' n = foldl' (\x _ -> dist a (x :+ 0)) 0 [1..n]
*Main Data.List> r'' 1000000
1000.0000000000299
(2.52 secs, 1,293,766,728 bytes)
magnitude 自体が重い処理なのでそこそこかかります。
fold を使ったコードは最初に説明した手続き的処理をそのまま置き換えている点に注目です。
手続き的なscanlの説明
参照
余談ですが (:+) の型は
Prelude Data.Complex> :t (:+)
(:+) :: a -> a -> Complex a
です。引数の型は何でもいいようです。ですので
Prelude Data.Complex> "hello" :+ "world"
"hello" :+ "world"
Prelude Data.Complex> :t it
it :: Complex [Char]
Prelude Data.Complex> :t (:+)
(:+) :: a -> a -> Complex a
です。引数の型は何でもいいようです。ですので
Prelude Data.Complex> "hello" :+ "world"
"hello" :+ "world"
Prelude Data.Complex> :t it
it :: Complex [Char]
もちろん演算とかはできません。
2017年12月9日土曜日
gist.github の罠
上のコードをコピペして実行する。
$ runghc a.hs
a.hs:3:11: error: Variable not in scope: n
たぶんこのようなエラーになるはずです。
最初はなぜエラーになるのか理解できませんでした。
Vim上ではまったく見た目は同じです。
カーソルをのせてみると違いがわかります。
show してみると
$ runghc b.hs
"n"
"\65358"
65358は、16進の"ff4e"
つまりUnicodeの小文字 n です。
対して2行目の n はアスキー。
これはコードを日本語入力がONのまま修正したことでおこりました。
見た目は同じでも異なる文字なのでエラーとなりました。
$ runghc a.hs
a.hs:3:11: error: Variable not in scope: n
たぶんこのようなエラーになるはずです。
最初はなぜエラーになるのか理解できませんでした。
Vim上ではまったく見た目は同じです。
カーソルをのせてみると違いがわかります。
show してみると
$ runghc b.hs
"n"
"\65358"
65358は、16進の"ff4e"
つまりUnicodeの小文字 n です。
対して2行目の n はアスキー。
これはコードを日本語入力がONのまま修正したことでおこりました。
見た目は同じでも異なる文字なのでエラーとなりました。
登録:
投稿 (Atom)
myPlayer
-- pipe.hs import System.Process import System.Environment main :: IO () a:_ IO [FilePath] randomize lst = do let c = length lst ...
-
この画像(IMGP2850.JPG)を表示します。 ただこのやり方だと元画像の大きさそのままで表示されます。 サイズを変更して表示するには一旦Pixbufのインスタンスをつくってから Buttonに貼り付けます。 かんたんな画像のビューアーをつくり...
-
上のコードをコピペして実行する。 $ runghc a.hs a.hs:3:11: error: Variable not in scope: n たぶんこのようなエラーになるはずです。 最初はなぜエラーになるのか理解できませんでした。 Vim上ではまったく...
-
pbmファイルでシェルピンスキーのギャスケットを描きます。 まずパスカルの三角形をつくります。 $ runghc -XParallelListComp pascal.hs 3 [1] [1,1] [1,2,1] [1,3,3,1] [1,4,6,4,1...