忍者ブログ
日々の研究生活のメモ書きなど
ただのメモです

普通maybe型の処理は、
let hoge = case hogemaybe of
 Nothing -> error $ "There is no hoge."
 _ -> fromJust hogemayby
みたいにしてやる

このhogeが[maybe a]リストなんかになっていたときは
import Data.Maybe に入っているcatMaybesが便利
リストのうち、Nothing以外のものだけを残してくれるらしい




PR
久しぶりに触ったのでかなり忘れていた

tupleから任意の要素を取り出すときは fst や snd を使う

ただし、この後の3つめを取り出したいときは、自分で関数を用意しないといけない・・・
fst' :: (a, b, c) -> a
fst' (x, _, _) = x
snd' :: (a, b, c) -> b
snd' (_, y, _) = y
thd' :: (a, b, c) -> c
thd' (_, _, z) = z
みたいなのを

4つ要素があるtupleの場合はもっと増やす。









■ 参考過去記事
【Haskell】readFileを使ったプレーンテキストの読み込み

以前も使ったけど、2列のデータを読み込みたい場合は・・・
Prelude> let a="1 2\n3 4\n5 6"
Prelude> map (map read) $ ( map words $ lines a ) ::[[Double]]
[[1.0,2.0],[3.0,4.0],[5.0,6.0]]
みたいな感じでとりあえずはOK
あくまでとりあえずは・・・・・


同期からのありがたいお言葉
Prelude> map (map read.words ).lines $ a ::[[Double]]
[[1.0,2.0],[3.0,4.0],[5.0,6.0]]
でもいけるらしい・・・








プログラムのあるパートからあるパートへの実行時間を表示したいときにその目安として時間を表示することがある

Haskellでは
Data.Time.Clock
にUTCを表示する関数が用意されている
import Data.Time.Clock

startUTC <- getCurrentTime
-- ここで何かやる
endUTC <- getCurrentTime
print $ diffUTCTime endUTC startUTC
のようなコードで
--ここで何かやる
の間の時間がわかるはず(あくまで目安)

■ 参考
http://hackage.haskell.org/package/time-1.5.0.1/docs/Data-Time-Clock.html












例えばこんなデータがあるとき、
0.327825
-1.760917
-1.238463
-0.636273
2.719690
0.452033
-0.993083
1.277327
-0.826901
-0.378082

Haskellでは、次のようにして読み込むことも可能(他にも色々と読み込み方はあるっぽいので、ただの一例)
channel1 <- readFile "data1.txt"
let hoge_data = map read $ lines channel1 :: [Double]
readFileをしただけだと、文字列として読み込まれるので
それをlinesで改行ごとに分割
さらにreadで文字列のリストをDoubleのリストに変換する


■ 参考
Haskell で文字列の分割と結合















Doubleなどの値をそのままprintすると、17桁表示されてしまう
定義上1.0になるべき値も17桁まで表示すると、計算誤差の都合で17桁目で1.0からずれてしまうことがある

そこで表示する桁数を絞って表示したくなる。

そのためにはshowFFloatなどを用いれば良いらしい
他にもあるのかもしれないが、ググってもこれしかHITしなかった・・・

■ 参考
Numeric.html

数値(Numeric)表示関数




import Numeric
read (showFFloat (Just 10) Value "") ::Double)
valueには桁数を落としたい数字を入れる
Just の後の10で桁数を決められる。
このままでは返り値がChar型になっているので、read関数を使ってDoubleに変換する

こんな感じでいいのだろうか?









Haskellでもコマンドラインで実行ファイルに引数を付けてみたくなった。
実行時に、引数を取って、それをあれこれ処理したい。
import System.Environment -- getArgs
inputFile <- getArgs
でおk
ghc 7.4からimportすべきmoduleがSystemではなく、System.Environmentになったらしいので注意
最初Systemにしていてエラーが出て気づいた・・・

■ 参考
GHC 7.4 で getArgs が System.Environment になってるメモ




ちなみに上記の例では、inputFileに["hoge"]のような文字列がリストに入ったかたちになる。
これでは少し手を加える必要があるので、文字列として使いたい場合は、
import System.Environment -- getArgs
[inputFile] <- getArgs
としてもよい


■ 参考
System.Environment












別に難しくはない
import System.Cmd
system "ls"
とかでおーけー
"ls"の部分を別のものに置き換えて使う。










例えば今、hmatrixというパッケージを使いたいとする
最新versionは
http://hackage.haskell.org/package/hmatrix
を見ると、0.15.2.1 が最新らしい
cabal update
cabal info hmatrix
として、詳細を確認すると、
* hmatrix (library)
Synopsis: Linear algebra and numerical computation
Versions available: 0.13.0.0, 0.13.1.0, 0.14.0.0, 0.14.0.1, 0.14.1.0,
0.15.0.0, 0.15.0.1, 0.15.2.0, 0.15.2.1 (and 31 others)
Versions installed: 0.14.0.1
Homepage: https://github.com/albertoruiz/hmatrix
Bug reports: [ Not specified ]
Description: Purely functional interface to basic linear algebra and other
numerical computations, internally implemented using GSL,
BLAS and LAPACK.

The Linear Algebra API is organized as follows:

- "Data.Packed": structure manipulation

- "Numeric.Container": simple numeric functions

- "Numeric.LinearAlgebra.Algorithms": matrix computations

- "Numeric.LinearAlgebra": everything + instances of standard
Haskell numeric classes
Category: Math
License: GPL
Author: Alberto Ruiz
Maintainer: Alberto Ruiz <aruiz@um.es>
Source repo: https://github.com/albertoruiz/hmatrix
Flags: dd, mkl, unsafe, finit, debugfpu, debugnan
Dependencies: base ==4.*, array -any, storable-complex -any, process -any,
random -any, vector >=0.8, binary -any, deepseq -any
Documentation: [ Not installed ]
Cached: No
Modules:
Data.Packed
Data.Packed.Development
Data.Packed.Matrix
Data.Packed.ST
Data.Packed.Vector
Graphics.Plot
Numeric.Container
Numeric.GSL
Numeric.GSL.Differentiation
Numeric.GSL.Fitting
Numeric.GSL.Fourier
Numeric.GSL.Integration
Numeric.GSL.Minimization
Numeric.GSL.ODE
Numeric.GSL.Polynomials
Numeric.GSL.Root
Numeric.LinearAlgebra
Numeric.LinearAlgebra.Algorithms
Numeric.LinearAlgebra.LAPACK
Numeric.LinearAlgebra.Util
表示された情報は上に貼ったURLリンクからも見ることができる
古いversionのパッケージをインストールしても他のパッケージのdependencyが満たされていることを確認しておく必要がある
portコマンドとかと違って、そういった整合性はユーザー自身が見なければならないらしい

最新versionをインストールしたいならば、
cabal install hmatrix
とすればよい
もしかしたらGSLが必要と言われるかもしれないが、そのときは別にインストールする




次に古いversionのパッケージをcabalインストールする方法について説明する

先ほどと同じ
http://hackage.haskell.org/package/hmatrix
のページに行き、インストールしたいversionをPropertiesの下のVersionsから選択する
例えば今、0.14.0.1がインストールしたい場合は
http://hackage.haskell.org/package/hmatrix-0.14.0.1

そしてDownloadsの下にある.tarをダウンロードする
あとは解凍して、中にあるINSTALLとかREADMEとかその辺りを参考にしてインストールすればよい

今回のhmatrixの場合はGSLがすでにインストールされていれば
cabal install
でオーケーでした







実はHaskellには型を推定してくれる機能があるのだ
hoge x = x * 2
とソースに書いておいて、
*Main> :t hoge
hoge :: Num a => a -> a

よゆー。




zipWith2 _ [] _ = []
zipWith2 _ _ [] = []
zipWith2 f (x:xs) (y:ys) = f x y : zipWith2 f xs ys
こんな関数でも?

*Main> :t zipWith2
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]

大丈夫です。



Hakellのメリットを簡単にかいつまんでまとめておく




遅延評価
与えられた値を必要になるまで評価(計算)しないこと
この性質により不必要な計算が行われる無駄をなくすことができる

コンピュータグラフィックスでも同じことをするらしい
例:レンダリング
画面に影響を与えない部分を計算しないことで、計算時間の無駄を省く


無限に繰り返すような関数を作っても、実際無限まで計算しなければ大丈夫らしい
例えば「何か演算をn回繰り返す関数」を作ったとしても大丈夫
これは無限に繰り返す可能性があるけど、必要なときに必要な回数しか計算しない




■ 参考リンク

プログラム・プロムナード/Haskellプログラミング(情報処理学会)





Haskellの勉強会を毎週やっている。
その備忘録



■ 関数を使ってみる

まずは次のような hoge.hs を作ってみる
-- で始まる行はコメントアウト
hoge.hs
doubleMe y = y + y
hoge x = x * 100

doubleUs x y = x * 2 + y * 2.0

-- 100より小さいと2倍にする関数
-- 最初のxは引数
-- = の後が返り値
doubleSmallNumber x = if x > 100
             then doubleMe x
             else x

-- 再起的に呼び出せるので、関数呼び出しの順番は関係ないらしい
-- if と else は2人で一つ
doubleSmallNumber2 x = succ ( doubleSmallNumber x )


if文を使うときはelseは必ず必要
またthenとelseはifよりも深いインデント(より右)になければならない


ghci上で呼び出すときはghciを起動してから
:l hoge
もしくは
:l hoge.hs



これで上の関数が使えるようになる
関数を実行するときに引数が必要なら、後ろに書く
上のソースだと、doubleUs には2つの引数が必要
double Us 1 2
みたいな感じ






■ リスト

ghci上でロード :l を使わずに、いろいろとやりたいときは let をつかう 


●関数の宣言
let lostnumbers = [4, 8, 15, 16, 23, 42]



●リストの連結
let listtetst = [1, 2, 3, 4 ]




●リストの先頭に追加
セミコロンを使うと、リストの先頭に要素を追加できる
ただしリストの中身と同じ型である
リストを全部読み込むわけじゃないので、5000万要素とかあってもだいじょうぶらしい
let 'A':" cat"
これで "A cat" が返ってくる


●リストの参照

let listhoge = [1, 2, 3, 4, 5] !! 0
とすると1が返ってくる
!! の後ろに要素の順番を書く
ちなみに数え方は最初が0から(C言語の配列と同じ)


他にもリストの要素の取り出し方がいろいろとあった
tail, head, last, init, take
-- 他は忘れました
ちょこちょことHaskellの勉強をしている。


■ コメントアウトの仕方

一行だけだと
-- hoge


複数行は
{-
hoge1
hoge2
-}
Haskellの利点すらきちんと理解していないのに、それでプログラムを書こうとするのはすごいと思う。
いろいろと使い方を調べたメモ書きです



■ コンパイラ

GHCというのをインストールする
Mac向けのバイナリもあるらしいけど、portにやってもらうことにした


port search ghc
sudo port install ghc

これで2つのものが使えるようになる


ひとつは ghc
これはソースを書いてコンパイルするためのコンパイラー

もうひとつは ghci
こっちはインタープリタ的な使い方ができる

まずは ghci を触っていく


■ ghci、大地に立つ

$ ghci
GHCi, version 7.4.2: http://www.haskell.org/ghc/ :? for helpLoading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude>



簡単な四則演算とかは省略

Haskellでは関数の後に括弧はいらないらしい
つまり
sqrt(2)
sqrt 2
でもおーけー


■ 画面出力

putStrLn "Hello, world"

putStr "Hello, world"
Lnのない方は改行しないだけ?

一つの式で複数の出力を使いたいときは do ブロッックを使う
do { putStr "1 + 1 = " ; print (1 + 1)}


丸括弧がいろいろと重要らしい


■ 入力

Prelude> do { n <- readLn ; print (n^2) }
2
4
2が入力で4が出力
Prelude> do { n <- getLine ; print (n) }
hoge
"hoge"
hogeが入力で "hoge" が出力

データの入力は readLn もしくは getLine
readLn はどんな型の値でも返す
getLine はStringで返す


# Haskell のソースコードのファイル尾は.hsがよく使われるらしい

# ハスー











HOME |
プロフィール
HN:coffee
職業:物理屋(自称)
趣味:映画鑑賞
自己紹介:
#include <stdio.h>
#include "MyProfile.h"

#define TWITTER coffee_pote

#define WISH_LIST
amazonのほしい物リスト
#ifdef RICH_FLAG
// ↑いつも支援いただきありがとうございます m(_ _)m
#endif


int main(void){

printf("\n");
printf("D論・・・? あぁそんな子もいましたね(執筆中)\n");
printf("\n");
printf("猿でもわかるgnuplot を執筆中(こっちの執筆は半年以上何も進んでいない・・・・)\n");
/* 最終更新 2017/07/19 */
return 0;

}
カウンター
ブログ内検索
ツイートするボタン
Flickr

Template "simple02" by Emile*Emilie
忍者ブログ [PR]