Haskell 代码只有在使用无可辩驳的模式时才起作用

Haskell 代码只有在使用无可辩驳的模式时才起作用,haskell,pattern-matching,Haskell,Pattern Matching,我有两个不同的文件,一个是use~,另一个是use explicit match $ diff a.hs b.hs 20,21c20 < (True, js) -> (True, a:js) < (False, js) -> (False, b:js) --- > ~(i, js) -> (i, (if i then a else b):js) 但是当我使用 (True, js) -> (True, a:js

我有两个不同的文件,一个是use
~
,另一个是use explicit match

$ diff a.hs b.hs
20,21c20
<       (True,  js) -> (True,  a:js)
<       (False, js) -> (False, b:js)
---
>       ~(i, js) -> (i, (if i then a else b):js)
但是当我使用

(True,  js) -> (True,  a:js)
(False, js) -> (False, b:js)
我的计算机没有响应(内存几乎已满)

我是否缺少任何模式?

整个文件都可以找到 . (不知道是否支持嵌入式gist)

我最初并没有编写代码,它是flickyfrans的一个修改版本


编辑:我想我应该在这里发布
b.hs
,以防止将来出现链接损坏的问题

import Data.Maybe

data Rose  a = Rose a [Rose a] deriving Show
newtype Graph a = Graph [(a, Rose a)]

lookupRose :: Eq a => a -> Graph a -> Rose a
lookupRose i (Graph rs) = fromJust $ lookup i rs

fromList :: Eq a => [(a, [a])] -> Graph a
fromList xs = graph where
  graph         = Graph $ map irose xs
  irose (i, is) = (i, Rose i $ map (`lookupRose` graph) is)

shortest :: [a] -> [a] -> [a]
shortest xs ys = snd $ shortest' xs ys where
  shortest' :: [a] -> [a] -> (Bool, [a])
  shortest' []     _      = (True,  [])
  shortest'  _     []     = (False, [])
  shortest' (a:as) (b:bs) = case shortest' as bs of
      ~(i, js) -> (i, (if i then a else b):js)

path :: Eq a => a -> a -> Graph a -> [a]
path orig dest gr = path' (lookupRose orig gr) where
  path' (Rose p ps)
      | p == dest = [p]
      | otherwise = p : foldr1 shortest (map path' ps)

-------------------------------------------------------------------------------

type Pos = (Int,Int)

posGraph :: [(Pos,[Pos])]
posGraph = [ (a, [b, c, d])
          , (b, [a, b, d])
          , (c, [a, d, e])
          , (d, [a, b, c, g])
          , (e, [c, e, f, h])
          , (f, [e, g, h])
          , (g, [d, f, g])
          , (h, [e, f])
          ]
  where [a,b,c,d,e,f,g,h] =
          [ (1,1)
          , (2,2)
          , (3,3)
          , (4,4)
          , (5,5)
          , (6,6)
          , (7,7)
          , (8,8)
          ]

main :: IO ()
main = do
  print $ path (1,1) (8,8) $ fromList posGraph
  print $ path (2,2) (8,8) $ fromList posGraph

你能举个例子吗?因为使用
True
/
False
,程序对我有效,Haskell不会显示任何错误。我认为问题在于,使用规则模式匹配,函数更严格,以后在程序中使用
foldr1…
。将
foldr
与严格的函数一起使用不是一个好主意,因为它会在返回任何内容之前立即执行所有递归调用,占用大量内存。不,因此不支持嵌入式gist,而且可能永远也不支持它们。GIST可以随时被删除,这会降低问题的价值。警告:如果运行wizzup的代码,请确保使用
-rtsopts
编译,并使用
+RTS-M2G
或类似工具,除非您确实喜欢交换内存。问题不在于
Bool
上的匹配。问题是模式
(x,True)
(x,False)
甚至
(x,y)
对元组是严格的。通过编写
~(x,y)
不仅可以在
Bool
上进行惰性匹配,还可以在元组上进行惰性匹配。也可以在
Bool
上尝试一个惰性匹配,即
(x,~y)
(提示:您将得到一个警告,因为
~
在那里是冗余的-它将炸毁堆栈,与
(x,y)
完全相同)并且
让(x,y)=最短“。。在..
中(它将起作用,因为
let
绑定中的模式匹配默认为惰性,而在
情况下
它默认为严格)。
import Data.Maybe

data Rose  a = Rose a [Rose a] deriving Show
newtype Graph a = Graph [(a, Rose a)]

lookupRose :: Eq a => a -> Graph a -> Rose a
lookupRose i (Graph rs) = fromJust $ lookup i rs

fromList :: Eq a => [(a, [a])] -> Graph a
fromList xs = graph where
  graph         = Graph $ map irose xs
  irose (i, is) = (i, Rose i $ map (`lookupRose` graph) is)

shortest :: [a] -> [a] -> [a]
shortest xs ys = snd $ shortest' xs ys where
  shortest' :: [a] -> [a] -> (Bool, [a])
  shortest' []     _      = (True,  [])
  shortest'  _     []     = (False, [])
  shortest' (a:as) (b:bs) = case shortest' as bs of
      ~(i, js) -> (i, (if i then a else b):js)

path :: Eq a => a -> a -> Graph a -> [a]
path orig dest gr = path' (lookupRose orig gr) where
  path' (Rose p ps)
      | p == dest = [p]
      | otherwise = p : foldr1 shortest (map path' ps)

-------------------------------------------------------------------------------

type Pos = (Int,Int)

posGraph :: [(Pos,[Pos])]
posGraph = [ (a, [b, c, d])
          , (b, [a, b, d])
          , (c, [a, d, e])
          , (d, [a, b, c, g])
          , (e, [c, e, f, h])
          , (f, [e, g, h])
          , (g, [d, f, g])
          , (h, [e, f])
          ]
  where [a,b,c,d,e,f,g,h] =
          [ (1,1)
          , (2,2)
          , (3,3)
          , (4,4)
          , (5,5)
          , (6,6)
          , (7,7)
          , (8,8)
          ]

main :: IO ()
main = do
  print $ path (1,1) (8,8) $ fromList posGraph
  print $ path (2,2) (8,8) $ fromList posGraph