Haskell에서 foldr를 사용하는이 함수가 작동하지 않는 이유를 이해하려고합니다.

gauss_is_king

그래서 저는 Haskell을 처음 접했고 WikiBooks를 사용하여 배우고 있습니다. 그리고 고차 함수 장에는 다음 예제가 사용됩니다.

echoes = foldr (\ x xs -> (replicate x x) ++ xs) []

그래서 그것을 실행하려고 시도했지만 다음과 같은 오류가 발생합니다.

 * Ambiguous type variable `t0' arising from a use of `foldr'
  prevents the constraint `(Foldable t0)' from being solved.
  Relevant bindings include
    echoes :: t0 Int -> [Int] (bound at HavingFun.hs:107:1)
  Probable fix: use a type annotation to specify what `t0' should be.
  These potential instances exist:
    instance Foldable (Either a) -- Defined in `Data.Foldable'
    instance Foldable Maybe -- Defined in `Data.Foldable'
    instance Foldable ((,) a) -- Defined in `Data.Foldable'
    ...plus one other
    ...plus 29 instances involving out-of-scope types
    (use -fprint-potential-instances to see them all)
* In the expression: foldr (\ x xs -> (replicate x x) ++ xs) []
  In an equation for `echoes':
      echoes = foldr (\ x xs -> (replicate x x) ++ xs) []

그리고 다음과 같이 쓰면 작동합니다.

echoes lis = foldr (\ x xs -> (replicate x x) ++ xs) [] lis

나는 이것에 대해 혼란스럽고 이것이 어떻게 든 관련된 점없는 함수 정의라고 생각합니까? 여기에 문제가 무엇인지 명확히하십시오. 내가 배우는 링크-https: //en.wikibooks.org/wiki/Haskell/Lists_III

좌회전

tl; dr

다만 항상 명시 적 유형의 서명을 작성 , 그런 이상한 문제에서 다음 이제 안전 (r)을.


이전에는 작동했지만 지금은 작동하지 않는 이유 foldr이전에 서명이 있었기 때문입니다.

foldr :: (a -> b -> b) -> b -> [a] -> b

WikiBooks가 가정하는 것이지만, 최신 GHC에서는 실제로 더 일반적인 서명이 있습니다.

foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b

이전 버전 단순히을 선택하여 특별한 경우입니다 t ~ []. 그들이 그것을 변경 한 이유는 배열이나 맵과 같은 다른 컨테이너를 접을 수도 있기 때문입니다. 사실, 당신의 코드에서

echoes = foldr (\ x xs -> (replicate x x) ++ xs) []

입력 컨테이너가 목록이 될 필요가 없으므로 실제로 서명과 완벽하게 작동합니다.

echoes :: Foldable t => t Int -> [Int]

... 다시 한 번 [Int] -> [Int]특별한 경우이므로 해당 함수를 다음과 같이 사용할 수 있습니다.

> echoes [1,2,3]
[1,2,2,3,3,3]

뿐만 아니라

> echoes $ Data.Map.fromList [('a',2), ('c',5), ('b',1)]
[2,2,1,5,5,5,5,5]

또는 함수에 목록 별 서명을 제공 할 수 있습니다.

echoes' :: [Int] -> [Int]
echoes' = foldr (\x xs -> (replicate x x) ++ xs) []

똑같이 작동 [1,2,3]하지만 Map.

문제는 왜 GHC가 이러한 서명 중 하나를 자체적으로 추론하지 않는가입니다. 글쎄요, 만약 하나를 선택해야한다면, Foldable사람들이 이것을 다른 컨테이너와 함께 사용해야 할 수도 있고 Foldable t =>수량 자를 계속 반복하고 싶지 않을 것이기 때문에 더 일반적인 버전 이어야합니다 . 그러나 이것은 또 다른 Haskell 규칙 인 monomorphism 제한 과 모순 됩니다 . echoes구현이 명시 적으로 매개 변수를 허용 하지 않기 때문에 (포인트없이 만 수행) 상수 적용 양식 이며, 다형성으로 명시 적으로 지정되지 않는 한 독립형 CAF는 단 형성 유형을 가져야합니다. 따라서 오류 메시지가 나타납니다. GHC는 이것이 단일형이기를 원하지만 무엇 을 제한 하는 정보가 없습니다.Foldable선택할 콘크리트 용기.

이 문제를 해결하는 방법에는 네 가지가 있습니다.

  • 아시다시피, 인수를 명시 적으로 범위로 가져옴으로써는 echoes더 이상 CAF가 아니므로 GHC는 다형성 유형을 유추합니다.

    echoes'' l = foldr (\x xs -> (replicate x x) ++ xs) [] l
    
    > :t echoes''
    echoes'' :: Foldable t => t Int -> [Int]
  • 단 형성 제한을 비활성화하면 GHC는 CAF인지 더 이상 신경 쓰지 않고 다음과 같은 일반적인 유형을 제공합니다.

    {-# LANGUAGE NoMonomorphismRestriction #-}
    echoes''' = foldr (\x xs -> (replicate x x) ++ xs) []
    
    > :t echoes'''
    echoes''' :: Foldable t => t Int -> [Int]
  • 권장 사항-XExtendedDefaultingRules 확장 기능을 켜면GHC가 자동으로[]CAF의 구체적인 단일 형태 컨테이너로선택합니다.

    {-# LANGUAGE ExtendedDefaultRules #-}
    echoes'''' = foldr (\x xs -> (replicate x x) ++ xs) []
    
    > :t echoes''''
    echoes'''' :: [Int] -> [Int]

    GHCi는 -XExtendedDefaultingRules기본적으로 활성화되어 있으므로 GHCi 프롬프트에서 함수를 선언하는 경우에도 마찬가지입니다.

  • 강력하게 권장 서명을 명시 적으로 지정하면 사용자와 GHC 모두 특별한 GHC 확장을 요구하지 않고 의도 된 내용을 정확히 알고 그에 따라 동작합니다.

    echoes :: Foldable t => t Int -> [Int]
    echoes = foldr (\x xs -> (replicate x x) ++ xs) []
    
    echoes' :: [Int] -> [Int]
    echoes' = foldr (\x xs -> (replicate x x) ++ xs) []
    
    > :t echoes
    echoes :: Foldable t => t Int -> [Int]
    > :t echoes'
    echoes' :: [Int] -> [Int]

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

재귀 함수에서 함수가 undefined를 반환하는 이유를 이해하려고합니다.

분류에서Dev

Dagger 2를 사용하여 ViewModel을 주입하고 @Provides가 작동 할 때 @Binds가 작동하지 않는 이유를 이해하려고합니다.

분류에서Dev

키 유형에서 참조를 사용하는 동안 람다 함수가 std :: lower_bound에서 작동하지 않는 이유는 무엇입니까?

분류에서Dev

생성자 함수를 변수에 할당합니다. -Firefox 콘솔을 사용하여이 코드가 작동하지 않는 이유

분류에서Dev

JDBC 드라이버를 사용하는 Oracle에서 pi () 함수가 작동하지 않는 이유는 무엇입니까?

분류에서Dev

SwiftUI를 사용하는 WatchOS에서 EmptyView ()가 작동하지 않는 이유는 무엇입니까?

분류에서Dev

Ionic Framework를 사용하는 Android 4.4에서 JavaScript Promise가 작동하지 않는 이유는 무엇입니까?

분류에서Dev

replace () 메서드가 예상대로 작동하지 않는 이유를 이해하지 못합니다.

분류에서Dev

jQuery를 사용하여 SVG 함수에 대한 변수를 정의하고 추가하는 것이 작동하지 않습니다.

분류에서Dev

Haskell, 함수는 숫자를 사용할 때 작동하지만 변수에는 작동하지 않습니다.

분류에서Dev

ResultSet.deleteRow ()가 Trim () 함수를 사용하는 쿼리와 함께 작동하지 않는 이유

분류에서Dev

react-native 및 react-router-native를 사용하는 동안 내 setTimeout 함수가 작동하지 않는 이유

분류에서Dev

함수에서 if 문을 사용할 때 JavaScript가 작동하지 않는 이유

분류에서Dev

concat 함수가 foldr를 사용하는 이유는 무엇입니까? 왜 접어

분류에서Dev

Google 스크립트를 사용하여 이메일로 보내기 위해 스프레드 시트에서 차트를 가져 오려고하는데 getAs () 함수가 작동하지 않습니다.

분류에서Dev

런타임 동안 오버로드 된 같음 메서드가 고려되지 않는 이유를 이해하는 데 도움이 필요합니다.

분류에서Dev

이 함수는 바이너리 트리에서 왼쪽 또는 오른쪽으로 이동해야하는지 알려주고 컴파일러는 & 연산자와 함께 결과를 사용하려고 할 때 오류를 반환합니다.

분류에서Dev

pvmismatch를 사용하는이 함수에 인수 전달 : 이것이 작동하지 않는 이유는 무엇입니까?

분류에서Dev

WASD를 사용하여 캔버스에서 이동하는 간단한 작업을 수행하지만 움직이지 않는 플레이어 개체를 작성하려고합니다.

분류에서Dev

이 상황에서 내가 문자 i를 사용하는 이유를 이해하지 못합니다.

분류에서Dev

SyRq를 사용하는이 일련의 키가 작동하지 않는 이유

분류에서Dev

@forward 이름 지정 접두사가 Sass를 사용하는 변수에서 작동하지 않는 이유는 무엇입니까?

분류에서Dev

appendChild를 사용하여 요소를 이동하는 것이 JS에서 작동하지 않는 이유

분류에서Dev

ajax를 사용하여 다른 페이지에서 div 및 해당 내용을 가져 오려고하면 작동하지 않습니다.

분류에서Dev

내 코드에서 ""을 (를) 사용하는 이유를 이해하지 못하지만 ''와 동일한 코드는 작동하지 않습니다.

분류에서Dev

이 함수에서 $ .each는 무엇이며 jQuery를 사용하지 않고 작동하도록 어떻게 다시 작성할 수 있습니까?

분류에서Dev

시프트를 사용하는이 스왑 매크로가 음수에 대해 작동하지 않는 이유는 무엇입니까?

분류에서Dev

.find 함수가 작동하지 않는 이유를 모르겠습니다.

분류에서Dev

Outlook에서 변수를 사용하여 네임 스페이스를 설정하는 것은 작동하지 않지만 입력하면 작동합니다.

Related 관련 기사

  1. 1

    재귀 함수에서 함수가 undefined를 반환하는 이유를 이해하려고합니다.

  2. 2

    Dagger 2를 사용하여 ViewModel을 주입하고 @Provides가 작동 할 때 @Binds가 작동하지 않는 이유를 이해하려고합니다.

  3. 3

    키 유형에서 참조를 사용하는 동안 람다 함수가 std :: lower_bound에서 작동하지 않는 이유는 무엇입니까?

  4. 4

    생성자 함수를 변수에 할당합니다. -Firefox 콘솔을 사용하여이 코드가 작동하지 않는 이유

  5. 5

    JDBC 드라이버를 사용하는 Oracle에서 pi () 함수가 작동하지 않는 이유는 무엇입니까?

  6. 6

    SwiftUI를 사용하는 WatchOS에서 EmptyView ()가 작동하지 않는 이유는 무엇입니까?

  7. 7

    Ionic Framework를 사용하는 Android 4.4에서 JavaScript Promise가 작동하지 않는 이유는 무엇입니까?

  8. 8

    replace () 메서드가 예상대로 작동하지 않는 이유를 이해하지 못합니다.

  9. 9

    jQuery를 사용하여 SVG 함수에 대한 변수를 정의하고 추가하는 것이 작동하지 않습니다.

  10. 10

    Haskell, 함수는 숫자를 사용할 때 작동하지만 변수에는 작동하지 않습니다.

  11. 11

    ResultSet.deleteRow ()가 Trim () 함수를 사용하는 쿼리와 함께 작동하지 않는 이유

  12. 12

    react-native 및 react-router-native를 사용하는 동안 내 setTimeout 함수가 작동하지 않는 이유

  13. 13

    함수에서 if 문을 사용할 때 JavaScript가 작동하지 않는 이유

  14. 14

    concat 함수가 foldr를 사용하는 이유는 무엇입니까? 왜 접어

  15. 15

    Google 스크립트를 사용하여 이메일로 보내기 위해 스프레드 시트에서 차트를 가져 오려고하는데 getAs () 함수가 작동하지 않습니다.

  16. 16

    런타임 동안 오버로드 된 같음 메서드가 고려되지 않는 이유를 이해하는 데 도움이 필요합니다.

  17. 17

    이 함수는 바이너리 트리에서 왼쪽 또는 오른쪽으로 이동해야하는지 알려주고 컴파일러는 & 연산자와 함께 결과를 사용하려고 할 때 오류를 반환합니다.

  18. 18

    pvmismatch를 사용하는이 함수에 인수 전달 : 이것이 작동하지 않는 이유는 무엇입니까?

  19. 19

    WASD를 사용하여 캔버스에서 이동하는 간단한 작업을 수행하지만 움직이지 않는 플레이어 개체를 작성하려고합니다.

  20. 20

    이 상황에서 내가 문자 i를 사용하는 이유를 이해하지 못합니다.

  21. 21

    SyRq를 사용하는이 일련의 키가 작동하지 않는 이유

  22. 22

    @forward 이름 지정 접두사가 Sass를 사용하는 변수에서 작동하지 않는 이유는 무엇입니까?

  23. 23

    appendChild를 사용하여 요소를 이동하는 것이 JS에서 작동하지 않는 이유

  24. 24

    ajax를 사용하여 다른 페이지에서 div 및 해당 내용을 가져 오려고하면 작동하지 않습니다.

  25. 25

    내 코드에서 ""을 (를) 사용하는 이유를 이해하지 못하지만 ''와 동일한 코드는 작동하지 않습니다.

  26. 26

    이 함수에서 $ .each는 무엇이며 jQuery를 사용하지 않고 작동하도록 어떻게 다시 작성할 수 있습니까?

  27. 27

    시프트를 사용하는이 스왑 매크로가 음수에 대해 작동하지 않는 이유는 무엇입니까?

  28. 28

    .find 함수가 작동하지 않는 이유를 모르겠습니다.

  29. 29

    Outlook에서 변수를 사용하여 네임 스페이스를 설정하는 것은 작동하지 않지만 입력하면 작동합니다.

뜨겁다태그

보관