4

Haskellで機能アプリケーションの順序に依存しないバージョンを実装したいと思います。少し背景として:自然言語のセマンティクスの著名な伝統(とりわけリチャードモンタギューに由来)は、式のセマンティック値(sv)としてさまざまなタイプのラムダ関数を割り当てます。文の真理値は、文の構成要素のsvに対して機能的な適用を実行することによって計算されます。簡単な例として、次のことを考慮してください。

tl = [1..10]

bill :: Int
bill = 1

tall :: Int -> Bool
tall = \x -> x `elem` tl

「Billistall」という文は、左の葉が「Bill」で占められ、右の葉が「tall」で占められている木と考えてください。葉のsvを左葉のsvに適用することにより、文の真理値を計算します。ここで、「ある人は背が高い」と考えてください。ここでは、左の葉が「ある人」[svのタイプ::(Int-> Bool)-> Bool]で占められ、右の葉が「背の高い」で占められています。 [svのタイプは::(Int-> Bool)]。の葉のsvをの葉のsvに適用することにより、文の真理値を計算します。

したがって、このシステムでは、左葉aと右葉bのツリーが与えられた場合最初どちらの葉が他方のドメインにあるかを確認し、それに応じて機能適用を適用します。aがbのドメインにある場合 b実行します。(a)、一方、bがaの定義域にある場合、 a(b)を実行します。

この種の「順序に依存しない」機能アプリケーションをHaskellに実装するにはどうすればよいですか?の結果を解析することにより、どのリーフが他のドメインにあるかを判別するいくつかの関数を作成しました。

show (typeOf a)

葉の場合a。しかし、これは私には不必要に面倒なようです。たとえば評価しようとすると、Ghciはエラーになります

bill tall

したがって、どのアイテムがもう一方のドメインにあるかを確認する簡単な方法は、一方のアイテムをもう一方のアイテムに適用して、エラー/例外が発生するかどうかを確認することです。それでは、私の質問は、型の不一致に起因する例外をどのようにキャッチするかということです。つまり、この種の非IO例外をキャッチするにはどうすればよいですか?

4

2 に答える 2

7

実行時に型の不一致をキャッチすることはできません。コンパイル時エラーです。(少なくとも、実行時にコードをコンパイルするために ghc-api を使用しないわけではありません。 ghciは ghc-api のラッパーであり、これがこれを実行できる理由です。) 実行するには、ADT でこの型の区別をキャプチャする方法を見つける必要があります。実行時にそれを使用するか、おそらく型クラスを使用します (ただし、これにより他の複雑さが生じます)。

于 2012-04-24T06:10:06.353 に答える
6

いくつかの型クラスの拡張機能を使用すると、長い道のりを歩むことができます:

{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies          #-}

class Copula l r where
  type Sem l r :: *
  is :: l -> r -> Sem l r

instance Copula (a -> b) a where
  type Sem (a -> b) a = b
  is = ($)

instance Copula a (a -> b) where
  type Sem a (a -> b) = b
  is = flip ($)   

たとえば、今定義すると

bill :: Int
bill = 1

tall :: Int -> Bool
tall = \x -> x `elem` tl

someMan :: (Int -> Bool) -> Bool
someMan = flip any [1 .. 20]

allMan :: (Int -> Bool) -> Bool
allMan = flip all [1 .. 20]

我々が得る

> bill `is` tall
True

> someMan `is` tall
True

> allMan `is` tall
False

簡単に言うと、

are :: Copula l r => l -> r -> Sem l r
are = is

我々はできる

> someMan `are` tall
True

> allMan `are` tall
False

少し見栄えがするかもしれません。

注:これはきれいに見えますが、一般に、ポリモーフィックなコンテキストでは、型チェッカーが何をすべきかを理解するのにかなりの助けが必要です。例えば

> [] `is` null

<interactive>:37:4:                                                              
    No instance for (Copula [a0] ([a1] -> Bool))
      arising from a use of `is'
    Possible fix:
      add an instance declaration for (Copula [a0] ([a1] -> Bool))
    In the expression: [] `is` null
    In an equation for `it': it = [] `is` null

その間

> ([] :: [Int]) `is` (null :: [Int] -> Bool)
True
于 2012-04-24T09:33:17.940 に答える