haskellでハマったところ

haskellを使っていてハマったところについてメモしておく

データ構築子のexport, import

下のコードの場合、型構築子はexportされるが、データ構築子はexportされない。なので別のモジュールにて型名としてのFugaが使われているからといってFugaをデータとして作ろうとするとコンパイルエラーとなる

module Hoge (Fuga) where

data Fuga = Fuga String

データ構築子まで全てexportする場合は以下のようにする

module Hoge (Fuga(..)) where

data Fuga = Fuga String

これはimportの際も同じである。

結合順序に関して

以下のコードはコンパイルエラーになる

print =<< forM [1,2,3] $ \a -> return a

<interactive>:3:1:
    Couldn't match expected type `(a2 -> m1 a2) -> t0'
                with actual type `IO ()'
    The first argument of ($) takes one argument,
    but its type `IO ()' has none
    In the expression: print =<< forM [1, 2, 3] $ \ a -> return a
    In an equation for `it':
        it = print =<< forM [1, 2, 3] $ \ a -> return a

<interactive>:3:11:
    Couldn't match expected type `IO a0'
                with actual type `(a1 -> m0 b0) -> m0 [b0]'
    In the return type of a call of `forM'
    Probable cause: `forM' is applied to too few arguments
    In the second argument of `(=<<)', namely `forM [1, 2, 3]'
    In the expression: print =<< forM [1, 2, 3]

$は右結合で優先度は最低であるため、上のコードは以下のものとして認識されることが原因

(print =<< forM [1,2,3]) $ \a -> return a

以下のどちらかにすればOK

結合している部分を明示
print =<< (forM [1,2,3] $ \a -> return a)

関数の引数としてまとめる
print =<< forM [1,2,3] (\a -> return a)

cabalファイルのexposed-modules

新しくmoduleを作って足す場合は.cabalファイル内のexposed-moduleに追記する必要がある
そうしないとlinkの際にエラーとなる(unknown symbolみたいな)
結構忘れる。

segmentation fault

このエラー自体あまり出ないがたまにある。原因は様々な可能性があるので一概にこれとは言えない。
自分が引っかかったのはghcのオプションとして--threadedをつけていないことだった。マルチスレッドなプログラムを一部で使っていたのだが、自分の作成したモジュール内ではこれをオプションとして定義していなかった。

すごいHaskellたのしく学ぼう!

すごいHaskellたのしく学ぼう!