Haskell的$ -Operator的定义

时间:2018-06-10 16:42:24

标签: haskell definition

postthis等其他来源坚持认为$ -operator的定义是

($) :: (a -> b) -> a -> b
f $ x = f x

($) f x = f x

($) = id

但我不明白为什么这个定义能够替换括号,所以我试图通过定义来自己重现并检查行为:

k :: (a -> b) -> a -> b
k f x = f x

但我得到的是:

-- these work:
(+2) `k` 4
(+2) `id` 4
sum `k` [1,2]
sum `id` [1,2]
map (flip(-)3) $ filter even `k`  filter (>=0) [-5..10]
map (flip(-)3) $ filter even `id` filter (>=0) [-5..10]

-- these don't:
sum `k`  1:[2]
sum `id` 1:[2]
map (flip(-)3) `id` filter even $ filter (>=0) [-5..10]

不应该k替代$吗?我做错了什么?

1 个答案:

答案 0 :(得分:9)

您错过了fixity declaration

import java.util.Iterator;
import java.util.Locale;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Function;
import java.util.function.LongConsumer;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

public class StreamProgress
{
    public static void main(String[] args)
    {
        int size = 250;
        Stream<Integer> stream = readData(size);

        LongConsumer progressConsumer = progress -> 
        {
            // "Filter" the output here: Report only every 10th element
            if (progress % 10 == 0)
            {
                double relative = (double) progress / (size - 1);
                double percent = relative * 100;
                System.out.printf(Locale.ENGLISH,
                    "Progress %8d, relative %2.5f, percent %3.2f\n",
                    progress, relative, percent);
            }
        };

        Integer result = stream
            .map(element -> process(element))
            .map(progressMapper(progressConsumer))
            .reduce(0, (a, b) -> a + b);

        System.out.println("result " + result);
    }

    private static <T> Function<T, T> progressMapper(
        LongConsumer progressConsumer)
    {
        AtomicLong counter = new AtomicLong(0);
        return t -> 
        {
            long n = counter.getAndIncrement();
            progressConsumer.accept(n);
            return t;
        };

    }

    private static Integer process(Integer element)
    {
        return element * 2;
    }

    private static Stream<Integer> readData(int size)
    {
        Iterator<Integer> iterator = new Iterator<Integer>()
        {
            int n = 0;
            @Override
            public Integer next()
            {
                try
                {
                    Thread.sleep(10);
                }
                catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
                return n++;
            }

            @Override
            public boolean hasNext()
            {
                return n < size;
            }
        };
        return StreamSupport.stream(
            Spliterators.spliteratorUnknownSize(
                iterator, Spliterator.ORDERED), false);
    }
}

或者在你的例子中:

infixr 0 $

Fixity声明告诉解析器中缀运算符的优先级/关联性是什么。