Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 将[Char]与读取的实例匹配_Haskell_Instance - Fatal编程技术网

Haskell 将[Char]与读取的实例匹配

Haskell 将[Char]与读取的实例匹配,haskell,instance,Haskell,Instance,我对用户定义的数据结构和Read 首先是我的数据结构 data Nat = Null | Succ Nat 我的read函数定义如下 readNatNat :: String -> Nat readNatNat xs |first == '(' = readNatNat (tail xs) |first == ' ' = readNatNat (tail xs) |firstFour == "Succ" = (Succ

我对用户定义的数据结构和
Read

首先是我的数据结构

data Nat = Null | Succ Nat
我的read函数定义如下

readNatNat :: String -> Nat
readNatNat xs   |first == '(' = readNatNat (tail xs)
                |first == ' ' = readNatNat (tail xs)
                |firstFour == "Succ" = (Succ (readNatNat(drop 4 xs)))
                |firstFour == "Null" = Null
                |b `elem` [0..] = toNatInt(b)
                 where b = (read(xs)::Int)
                    first = head xs
                    firstFour = take 4 xs

toNatInt :: Int -> Nat
toNatInt x | x==0 = Null
       | x<0 = error "Unter Null gibts kein Int 2 Nat"
       | otherwise = Succ(toNatInt(x-1))
instance Show Nat where
     show (Succ a) = showsRealSucc(Succ a)
     show Null = show "Null"

showsRealSucc :: Nat -> String
showsRealSucc Null = "Null"
showsRealSucc (Succ a) = (if a/= Null then ("Succ ("++showsRealSucc(a)++")") 
                                      else "Succ Null")
对其他实例(如
Enum
Eq
Show
等)进行编程非常简单。 我知道
Read
需要一个Int,但我不知道为什么;)

我认为
Read
show
相反,它获取一个
String
并将其解析到我的数据结构中

我这样定义了
Show

readNatNat :: String -> Nat
readNatNat xs   |first == '(' = readNatNat (tail xs)
                |first == ' ' = readNatNat (tail xs)
                |firstFour == "Succ" = (Succ (readNatNat(drop 4 xs)))
                |firstFour == "Null" = Null
                |b `elem` [0..] = toNatInt(b)
                 where b = (read(xs)::Int)
                    first = head xs
                    firstFour = take 4 xs

toNatInt :: Int -> Nat
toNatInt x | x==0 = Null
       | x<0 = error "Unter Null gibts kein Int 2 Nat"
       | otherwise = Succ(toNatInt(x-1))
instance Show Nat where
     show (Succ a) = showsRealSucc(Succ a)
     show Null = show "Null"

showsRealSucc :: Nat -> String
showsRealSucc Null = "Null"
showsRealSucc (Succ a) = (if a/= Null then ("Succ ("++showsRealSucc(a)++")") 
                                      else "Succ Null")
为了让您了解Nat:

它是自然数的表示形式,因此当我键入
readnat“3”
时,输出为
“(成功(成功(成功无效))”

提前谢谢

readsPrec
采用优先参数 所以

readsPrec
采用一个附加的
Int
参数来指示周围上下文中的优先级,因此,例如,如果您正在读取
Just Null
,则周围的优先级为10,函数应用程序

在您的情况下,我认为您可以使用实用程序函数
readParen::Bool->ReadS a->ReadS a
来处理:

instance Read Nat where
readsPrec prec = readParen prec natReads where
  natReads xs = [(readNatNat xs,"")]
readsPrec
应该是一个小型解析器
  • 如果解析失败,您应该返回
    []
    ,而不是导致错误
  • 您应该在剩余的
    字符串
    部分中返回输入的剩余部分
  • (应该有一个可能的解析列表)
  • 3。成功和成功的列表
    2.返回剩余部分:

    这种变通方法不适用于
    readsPrec
    的工作方式。列表
    [(a,String)]
    应该由可能的解析和剩余字符串组成,因此
    readsPrec 5“Null,Null,suc Null]”
    应该是
    [(Null,Null,suc Null]”]
    。正如我在这里试图提示的那样,在解析值列表等时可以使用未使用的输入的剩余部分

    重要提示:
    如果您不这样做,您很可能从
    读取“[Null,succnull]”
    中得到错误的结果

    很少会有多个可能的解析,但例如,如果您决定将
    Nat
    值显示为
    “0+1+1”
    ,则需要为该输入生成列表
    [(Null,+1”),(suc Null,+1”),(suc(suc Null),”)]

    这意味着您应该在进出的过程中检查括号的数量,以便在剩余字符串中返回适当的金额:
    readsPrec 3“((Succ(Succ-Null);”)”
    应该是
    [(Succ(Succ-Null),”))]

    1。不要引起错误,返回[]

    如果输入不是有效的Nat,则需要返回
    []
    。我发现了三个问题:

      where b = (read(xs)::Int) -- could crash
    
      first = head xs  -- could crash
    
      | x<0 = error "Unter Null gibts kein Int 2 Nat" -- crashes
    

    这样您就可以
    fmapPairs-Succ(readParen-False)
    找到
    “Succ”
    时的剩余部分。如果你需要更多的提示来完成这项工作,请告诉我(我认为你已经证明了自己的能力,这是一个很好的练习,因为你已经了解了更多关于
    readsPrec
    ).

    请提供
    Read
    实例。如果查看
    Read
    类,您将看到它定义函数
    readsPrec::Int->String->[(a,String)]
    。您的函数显然没有这种类型。第一个参数是一个优先上下文,用于更开明的解析。返回类型必须是解析和剩余字符串的列表。要将函数转换为有效格式,您可以编写
    readsPrec\ux=[(readnat x,”)
    @user2407038。信不信由你,这就是我在回答时想说的全部内容,但我想我有点得意忘形了!在不编写正确的
    readsPrec
    的情况下修复类型错误的问题是,有时在读取列表等时会遇到问题。末尾的字符串应该是未使用的输入,
    readsPrec
    不应该像
    readnat
    在无效输入时那样崩溃-它应该只返回
    []
      where b = (read(xs)::Int) -- could crash
    
      first = head xs  -- could crash
    
      | x<0 = error "Unter Null gibts kein Int 2 Nat" -- crashes
    
    fmapPairs :: (a -> b) -> [(a,String)] -> [(a,String)]
    fmapPairs f pairs = [(f a,xs) | (a,xs) <- pairs]