2016-07-14 13 views
2

私はHaskellを初めて使いました。関数の結果から値を取得する方法は混乱しています。私の場合は、Haskellのファイルを解析し、どのASTノードがどの行に表示されるのかを調べようとしています。これは、これまで私が持っているコードです:Haskell Objectからの情報の抽出

import Language.Haskell.Parser 
import Language.Haskell.Syntax 

getTree :: String -> IO (ParseResult HsModule) 
getTree path = do 
       file <- readFile path 
       let tree = parseModuleWithMode (ParseMode path) file 
       return tree 

main :: IO() 
main = do 
     tree <- getTree "ex.hs" 
     -- <do something with the tree other than print it> 
     print tree 

は、だから私はコメントを持っている行に、私はtreeとして構文木を持っています。タイプがParseResult HsModuleのようです。私が欲しいのはちょうどHsModuleです。私は次のように私が探していますが機能だと思います:

extract :: ParseResult a -> a 

いっそ、一般的なHaskellの機能

extract :: AnyType a -> a 

たぶん私はここにハスケルに関する主要な概念が欠けていますか?

P.S.私は、これらのことを「対象」として考え、そこから「フィールド」にアクセスしようとすることは間違っていることを理解していますが、このようなことを一般的にどのように扱うか説明したいと思います。

答えて

3

ParseResultの定義は次のとおりです。

data ParseResult a = ParseOk a | ParseFailed SrcLoc String 

だから二つの可能性があります(ソースコードから得た):構文解析のいずれかが成功し、それがParseOkインスタンスを返します、または何かが間違っていましたその場合は構文解析中にエラーの場所を取得し、エラーメッセージにはParseFailedコンストラクタを使用します。

だから、関数を定義することができます

getData :: ParseResult a -> a 
getData (ParseOk x) = x 
getData (ParseFailed _ s) = error s 

それは常に可能であるため、あなたのコンパイラ/インタプリタ/アナライザは/ ...含むHaskellのプログラムを解析するだけでなく、エラーをスローすることをお勧めします構文エラー。

+2

'getData'は偽です。パースエラーを処理するには、 'error'を使うことは間違った方法です。 – dfeuer

1

私はちょうどこれを行う方法を考え出しました。私が私が実際に代わり

extract :: ParseResult a -> a 
extract (ParseOk a) = a 

を使用するために必要な

extract :: ParseResult a -> a 
extract (ParseResult a) = a 

を定義しようとしていたときと思われます。私はこれがなぜ100%確かではない。

+1

警告をオンにすることを忘れないでください。「ParseFailed」のケースを処理するのを忘れたことを指摘します。 2つの可能な結果(成功と失敗)を持つことは、 'ParseResult'の全体的なポイントです。 – chi

+0

これは、 'ParseResult a'が型であるためです。パターンマッチングは、値レベルのパターンのみを受け入れます。そのため、パラメータをデータコンストラクタに一致させる必要があります。それは 'たぶん'に匹敵する。 'たぶんa'型の値から値を抽出するには、'おそらく 'ではなく' Just'にマッチさせる必要があります。それは意味をなさないでしょう。 – baxbaxwalanuksiwe

7

確かにハスケルについて大きな誤解を示してい

extract :: AnyType a -> a 

タイプ

の一般的な機能を探しています。 AnyTypeのような多くのものを考えてみましょう。オブジェクトから正確に1つのオブジェクトを抽出する方法もあります。 Maybe Intはどうですか? Just 5から 5に簡単に変換することはできますが、 Nothingで返すべき数字は何ですか?

AnyType[]の場合は、[String]になりますか?

extract ["help", "i'm", "trapped"] 

または

extract [] 

の結果は何をすべきですか?

ParseResultは、ParseOkを使用して、すべてが正常であることを示す結果を格納し、エラーを示すParseFailedを使用するという点で、同様の「問題」があります。パースが成功すると、不完全なパターンマッチが結果を得ますが、パーズが失敗した場合はプログラムがクラッシュします。 ParseResultを使用することによって、Haskellは、分析しているコードが適切に解析されていなければ、何がすべきかを検討することを奨励しています。

+0

それは理にかなっています。私が理解していなかったのは、 'ParseResult'には2つの可能な値しかありません:' ParseOk'と 'ParseFailed'は実際の値(成功の場合は' HsModule'と 'SrcLoc'&' String'失敗の場合)。 – nullromo

関連する問題