3

このコードを で実行しようとしていますghci:

http://www.cs.rutgers.edu/~ccshan/prepose/Prepose.hs

これは、論文「Functional Pearl: Implicit Configurations」に関連付けられているコードです。

http://www.cs.rutgers.edu/~ccshan/prepose/prepose.pdf

私はいくつかのLANGUAGEプラグマが欠けていると確信しています...次のエラーが発生しています:

Prepose.hs:39:1: Parse error in pattern: normalize

また、この論文に関連するハックパッケージはありますか?

4

3 に答える 3

4

関数定義パターンに型シグネチャを適用することはできません。これは、構文的に正しい書き方です。

normalize :: (Modular s a, Integral a) => a -> M s a
normalize a = M (mod a (modulus (__ :: s))) :: M s a

しかし、それはうまくいきません。本当に必要なのは、関数の型シグネチャで型変数sを参照することです。これは、明示的な数量化を必要とする ScopedTypeVariables 拡張機能を使用して行うことができます。

normalize :: forall a s. (Modular s a, Integral a) => a -> M s a
normalize x = M (Mod x (modulus (__ :: s)))

コードを改善するための提案として、タグ付きライブラリを使用することをお勧めします。

import Data.Proxy

modulus :: (Modular s a) => Proxy s -> a

これにより、醜いプレースホルダーボトムなしでうまくいくことができます. 別の書き方は次のとおりです。

modulus :: (Modular s a) => Tagged s a

これにより、概念的なメリットも得られます。Modモジュラー値とTaggedそのモジュライの 2 つの型が得られます。タイプを自分で定義して、より適切な名前を付けることもできます。

newtype Mod     s a = Mod     { residue :: a } 
newtype Modulus s a = Modulus { modulus :: a }

これはさておき、これを実際に使用したい場合は、ocharles が言ったことをお勧めします:リフレクションライブラリを使用してください。

于 2013-02-09T20:24:14.277 に答える
3

コードの問題は解決できませんが、EdwardKmettの「リフレクション」ライブラリはその論文に基づいています。

于 2013-02-09T19:45:31.920 に答える
2

reflectionこれで、ライブラリを使用した論文の例が完成しました。Monoidこの例は、ライブラリソースの例に基づいています。

data M a s = M a -- Note the phantom comes *after* the concrete

-- In `normalize` we're tying the knot to get the phantom types to align
-- note that reflect :: Reifies s a => forall proxy. proxy s -> a

normalize :: (Reifies s a, Integral a) => a -> M a s
normalize a = b where b = M (mod a (reflect b)) 

instance (Reifies s a, Integral a) => Num (M a s) where
  M a + M b = normalize (a + b)
  ...

withModulus :: Integral a => a -> (forall s. Reifies s a => M a s) -> a
withModulus m ma = reify m (runM . asProxyOf ma)
  where asProxyOf :: f s -> Proxy s -> f s
        asProxyOf a _ = a
于 2013-02-09T20:38:13.397 に答える