Şimdiye kadar çok iyi çalışan Haskell'de bir yazılan ifade ayrıştırıcısı oluşturmaya çalışıyorum, ancak şu anda daha yüksek sipariş işlevlerini uygulamaya çalışıyorum. Ben basit bir örnek aşağı sorunu haşlanmış ettik:Yazılı ifade ayrıştırıcısı
{-# LANGUAGE TypeFamilies,GADTs,FlexibleContexts,RankNTypes #-}
-- A function has an argument type and a result type
class Fun f where
type FunArg f
type FunRes f
-- Expressions are either constants of function applications
data Expr a where
Const :: a -> Expr a
App :: Fun f => f -> FunArg f -> Expr (FunRes f)
-- A very simple function
data Plus = Plus
-- Which takes two integer expressions and returns an integer expression
instance Fun Plus where
type FunArg Plus = (Expr Int,Expr Int)
type FunRes Plus = Int
-- A more complicated function which lifts a function to lists (like in haskell)
data Map f r = Map f
-- For this we need the concept of lifting function arguments:
class Liftable a where
type LiftRes a
-- A singleton argument is lifted by changing the expression type from a to [a]
instance Liftable (Expr a) where
type LiftRes (Expr a) = Expr [a]
-- Two function arguments are lifted by lifting each argument
instance (Liftable a,Liftable b) => Liftable (a,b) where
type LiftRes (a,b) = (LiftRes a,LiftRes b)
-- Now we can declare a function instance for Map
instance (Fun f,Liftable (FunArg f),r ~ LiftRes (FunArg f)) => Fun (Map f r) where
type FunArg (Map f r) = r
type FunRes (Map f r) = [FunRes f]
-- Now a parser for functions:
parseFun :: [String] -> (forall f. Fun f => f -> a) -> a
-- The parser for the plus function is easy:
parseFun ["plus"] f = f Plus
-- But the parser for map is not possible:
parseFun ("map":sym) f
= parseFun sym (\fun -> f (Map fun))
sorun özyinelemeli sınıf bildirimleri girişi yasak olduğu için, her LiftRes kendisi kalkar her bir tip kontrolörü ikna yolu yoktur olduğunu gibi görünüyor.
Sorum şu: Bu işi nasıl yaparım? Ipuçlarını alabildiğim başka ifade parsers örnekleri var mı?
EDIT: Görünüşe göre this discussion about type family constraints çok ilgili görünmektedir. Ancak, çözümlerini benim durumumda çözemedim, belki birisi buna yardımcı olabilir?
fonksiyon sınıfına 'Liftable' kısıtlama ekleme ile sorun bu daha sonra kalkar her' örneğini gerektirir Harita örneğine 'kalkar her r' eklemek için beni gerektirir (LiftRes (FunArg f))' ayrıştırıcıda. Bu süreç sonsuza kadar devam edilebilir. Yorumunuzu onaylama: Gerçek kodda lisp ifadelerini ayrıştırıyorum, ancak ek paketler yüklemek zorunda kalmadan okuyucuları rahatsız etmek istemedim. – henning
Teşekkürler, bu diğer yazı da (Bence) alıyor. Ancak, kodunuzu çalışmaya başlayamıyorum, önceki gibi aynı hata mesajını veriyor. Başka bir şey değiştirmek zorunda mıyım? Yoksa bazı derleyici bayrakları vb. Eksik miyim? – henning
Sadece bunları nasıl kullandığınızı söyleyebilirim. Aldığınız asıl hata, örneğinizle tekrarlanamazsa, senaryosunda gerçekten işe yarayan bir şey önermek benim için zor. – kosmikus